I'm very new to C, this is the first program I'm writing in it. My professor gave us a function for allocating memory for a 2d array, called malloc2d. I am supposed to modify it to allocate memory for a 3d array, but being so new to C I am not sure how to go about it. I've tried looking at other malloc functions for 3d arrays but none of them look similar to the one I was given. Similarly, we have a free2d function that also needs to be modified for a 3d array. Here are the functions to be modified:
void** malloc2D(size_t rows, size_t cols, size_t sizeOfType){
void* block = malloc(sizeOfType * rows * cols);
void** matrix = malloc(sizeof(void*) * rows);
for (int row = 0; row < rows; ++row) {
matrix[row] = block + cols * row * sizeOfType;
}//for
return matrix;
}//malloc2D
void free2D(void*** matrix){
free((*matrix)[0]);
free((*matrix));
matrix = NULL;
}//free2D
Any help or a start would be greatly appreciated.
I find it difficult to believe this is a first exercise; it is moderately tricky, at least.
Fix the 2D code
The first step should be to clean up the
malloc2D()
function so it doesn't casually use a GCC extension — indexing avoid *
— because Standard C does not allow that (becausesizeof(void)
is undefined in Standard C; GNU C defines it as 1). Also, the bug infree2D()
needs to be fixed; the last line of the function should read*matrix = NULL;
(the*
was omitted). That code should be tested too, because the correct way to access the matrix is not obvious.Here's some modified code (variables renamed for consistency with the 3D version) that tests the revised 2D code:
When run on a MacBook Pro running macOS High Sierra 10.13.3, compiling with GCC 7.3.0, I get the output:
With the monster allocation included, the trace ended:
Adapt to 3D code
I chose to call the leading dimension of the 3D array a 'plane'; each plane contains a 2D array with
r
rows byc
columns.For me, I drew myself a diagram to convince myself I was getting the assignments correct — after I'd messed up a couple of times. In each cell in the first two tables, the first number is the index number of the cell in the containing array (
level1
in the first table) and the second is the index number of the cell in the next level (level2
in the first table). The numbers in thelevel3
table are simply the indexes into the array ofdouble
a.With that diagram in place — or a paper and pen version with arrows scrawled over it, the values in the cell of plane
p
inlevel1
isp * rows
; the values of in the cell of planep
, rowr
inlevel2
isp * rows + r) * cols
; the values in the cell of planep
, rowr
, cellc
inlevel3
is(p * rows + r) * cols + c
. But the values are not integers; they're pointers. Consequently, the values have to be scaled by an appropriate size and added to the base address for thelevel1
,level2
orlevel3
space.That leads to code like this:
Example output (with outsize memory allocation):