4

I am currently writing a function which uses a bi-dimensional array of pointers to a structure cell. I'll have to update each cell with data read in a file. As I will need to access the various cells, I have to deal with dynamic allocation. But what is the best way to use it here, as I don't need access to the array itself ? Can I use:

cell *p_cell[height][width] = malloc(height*width*sizeof(cell*));

Or:

cell *p_cell[height][width];

and then later on (in a for loop, for instance) :

p_cell[i][j] = malloc(sizeof(cell*));
chqrlie
  • 131,814
  • 10
  • 121
  • 189
narfi
  • 43
  • 5
  • 1
    `cell *p_cell[height][width] = malloc(height*width*sizeof(cell*));` is not valid C, so cannot use that. Maybe you are thinking `cell (*p_cell)[height][width] = malloc(height*width*sizeof(cell*));`? Without knowing the application goals, the "best way" is not discernible without a broad discussion. – chux - Reinstate Monica Feb 12 '17 at 15:08
  • 1
    This `cell *p_cell[height][width];` already allocates an `height`x`width` sized array of pointers to `cell`, namely `p_cell`. – alk Feb 12 '17 at 15:08

3 Answers3

4
data_type (*array) [width] = malloc( sizeof(data_type[height][width]) );

Now you can access the data using arr[i][j]

P.S: 2-D array should should be allocated as a contiguous chunk of memory, to get the best read write performance.

**Edit : ** As pointed out by chux in comment section that array is not a 2-D array, it's a pointer to 1-D array.

In order to make array as 2-D array, you need to declare it like this.

data_type (*array) [height][width] = malloc( sizeof(data_type[height][width]) );
Shravan40
  • 8,922
  • 6
  • 28
  • 48
2

It seems like you want a 2D array of pointers, which can be declared as:

cell *p_cell[height][width];

To allocate each of these cell * pointers in p_cell[i][j], you can do this:

for (size_t i = 0; i < height; i++) {
    for (size_t j = 0; j < width; j++) {
        p_cell[i][j] = malloc(sizeof(cell));
        /* check malloc */
        /* access using p_cell[i][j]->something */
    }
}
RoadRunner
  • 25,803
  • 6
  • 42
  • 75
  • Thank you ! That's exactly what I wanted. I had a huge amount of memory errors on Valgrind, reduced to no errors at all with your solution ! – narfi Feb 12 '17 at 16:27
2

Here are two ways to allocate your 2D array:

cell *(*p_cell)[height][width] = malloc(sizeof(*p_cell));

p_cell is a pointer to a 2D array of pointers to cell objects. Item at coordinates i, j is retrieved with:

cell *p = (*p_cell)[i][j];

It is probably easier to make p_cell a pointer to an array of arrays:

cell *(*p_cell)[][width] = malloc(height * sizeof(*p_cell));

You would get the item at coordinates i, j with

cell *p = p_cell[i][j];

The above arrays are uninitialized, you would need to initialize them with pointers to existing cell objects or pointers to allocated cell objects.

If the 2D array is only used locally in your function and dimensions width and height are not too large, you can define the 2D array with local storage:

 cell *p_cell[height][width];

As width and height are dynamic values, static initialization is not available. You must initialize this array with a nested loop, like the allocated ones.

The question is: Do you really need the element type to be a pointer to cell?. It is only useful if you are going to make some of these pointers point to the same object or have a null value, or point to cell objects referenced elsewhere. Otherwise, it would be much easier to use an array of cell objects, either local to the function or allocated with malloc() or calloc():

cell p_cell[][width] = calloc(sizeof(*p_cell), height);
chqrlie
  • 131,814
  • 10
  • 121
  • 189