2

As title, I want to know how to initialize double pointer with sizeof a pointer.

For instance

int **p=malloc(sizeof *p * rows);

for(size_t i = 0; i < rows; i++){
    p[i]=malloc(sizeof ? * cols);
}

What should I fill in ?.

Any help would be appreciated.

Steven
  • 27
  • 4
  • 4
    `sizeof **p` would work, as would `sizeof *p[0]` or `sizeof *p[i]` or `sizeof p[i][0]`. All of those are the same, so choose whichever is clearest (in menaing) to you – Chris Dodd Dec 20 '21 at 01:25
  • 1
    Generally, you should never write code like this unless you have specialized requirements. To allocate a 2D array, simply do `int (*arr)[cols] = malloc( sizeof(int[rows][cols]) );`. No loops. Unless you actually need each now to have individual sizes or similar specialized requirements. – Lundin Dec 20 '21 at 08:28
  • See [Correctly allocating multi-dimensional arrays](https://stackoverflow.com/questions/42094465/correctly-allocating-multi-dimensional-arrays) for details. – Lundin Dec 20 '21 at 08:30
  • 1
    To allocate for a pointer to a "2D" array, code can use the simple `int (*p)[row][cols] = malloc(sizeof *p);`, but then access looks like `(*p)[r][c]`. – chux - Reinstate Monica Dec 20 '21 at 12:35

2 Answers2

5

What should I fill in ?.

In general when you have

X = malloc(sizeof ? * NUMBER);

the ? is to be replaced with the type that X points to. That can simply written as *X.

So the line:

p[i]=malloc(sizeof ? * cols);

is to be:

p[i]=malloc(sizeof *p[i] * cols);

Notice that a 2D array can be created much simpler. All you need is

int (*p)[cols] = malloc(sizeof *p * rows);

Here p is a pointer to an array of cols int. Consequently sizeof *p will be the size of an array of cols int.

Using this VLA based technic means that you can allocate the 2D array using a single malloc. Besides making the code more simple (i.e. only 1 malloc) it also ensures that the whole 2D array is in consecutive memory which may give you better cache performance.

Support Ukraine
  • 42,271
  • 4
  • 38
  • 63
  • This should be the accepted answer, if the col length is the same for all elements one should create a pointer a VLA array instead to only get 1 call to malloc. – Fredrik Dec 20 '21 at 03:26
  • Note that `int (*p)[cols]` is no longer an OP "double pointer", yet is still a good idea to consider. – chux - Reinstate Monica Dec 20 '21 at 12:31
1

It looks like you want p to be an array that can hold pointers, and the number of pointers is rows. So you can allocate memory for p like this:

int ** p = malloc(sizeof(int *) * rows);

Now if you want p[i] to point to an array that holds cols ints, do this:

p[i] = malloc(sizeof(int) * cols);
David Grayson
  • 84,103
  • 24
  • 152
  • 189
  • Thanks for your answer, that's really helpful. But I want to initialize with `sizeof` a pointer (just curious). – Steven Dec 20 '21 at 01:33
  • What do you mean? Your secondary allocations are for arrays of *ints*, not pointers, so it's best to use `sizeof(int)` or use `sizeof(x)` where `x` is some variable of type `int`. – David Grayson Dec 20 '21 at 01:35
  • I get it. Thanks a lot. – Steven Dec 20 '21 at 01:43