2

How to dynamically allocation memory for pointer of array? (*p)[4]

int main()
{
    int (*p)[4];
    int i;
    for (i=0;i<4;i++)
       (p)[i]=(int*)malloc(4);
    printf("a");
    return 0;
} 

on code::blocks, it says:

error: incompatible types when assigning to type 'int[4]' from type 'int *'|
Natan Streppel
  • 5,759
  • 6
  • 35
  • 43
user2645384
  • 21
  • 1
  • 3

3 Answers3

0

You are mixing a pointer to an array of integers (your declaration) with an array of integer pointers (the assignment). You can either change your declaration to:

int *p[4];

In which case your assignment will work. Or, you can simply remove the malloc since your declaration as it stands already has four integers allocated. However, if you want the integers as an automatic the code would be more readable if the declaration were:

int p[4];

Since that's basically the same thing. You can just pass in &p if you want a pointer to an array of integers later on.

0

In your declaration int (*p)[4];, p is a pointer to array of int type and 4 length, but p is just a pointer it doesn't point to any array. So you can assign to (*p)[i].

Notice parenthesis around *p is needed as precedence of [] operator is higher then * deference operator. So (p)[i] is very wrong.

First understand how to use pointer to array check following example:

#include<stdio.h>
int main(){
  int b[4] = {1, 2, 3, 4}; 
  int  i;
  int (*p)[4] = &b;
  for(i = 0; i < 4; i++){
     printf(" b[%d] = (*p)[%d] = %d\n", i, i, (*p)[i]);
  }
  return 1;
}

Output:

 b[0] = (*p)[0] = 1
 b[1] = (*p)[1] = 2
 b[2] = (*p)[2] = 3
 b[3] = (*p)[3] = 4

Check working code @codepad.

Now, How can you use dynamic memory allocation for p pointer? Check following example:

#include<stdio.h>
#include<stdlib.h>
int main(){
  int  i;
  int (*p)[4];
  p = malloc(4 * sizeof(int)); // allocation 
  // assignments 
  for(i = 0; i < 4; i++){
    (*p)[i] = i * i;
  }
  for(i = 0; i < 4; i++){
     printf(" (*p)[%d] = %d\n", i, (*p)[i]);
  }
  return 1;
}   

compile it as: gcc -Wall -pedantic xx.c check code working @codepad.

I would suggest you avoid casting returned address from malloc and calloc functions in C, regarding this read Do I cast the result of malloc?.

Community
  • 1
  • 1
Grijesh Chauhan
  • 57,103
  • 20
  • 141
  • 208
  • So what is the difference between `int (*p)[4]; p = malloc(4 * sizeof(int));` and `int *p; p = malloc(4 * sizeof(int));`? What does `p` hold in the first case? – HelloWorld123456789 Feb 12 '14 at 13:58
  • I think `p` and `*p` will contain the same value for the first case. – HelloWorld123456789 Feb 12 '14 at 14:02
  • @RikayanBandyopadhyay when you declares `p` as `int (*p)[4];` then `p` is pointer to array. If you wants to access elements of array pointed by `p` then correct syntax is `(*p)[i]` If you declares `p` is `int* p` then `p` is just a pointer to `int` and `p[i]` is correct syntax. Regarding malloc I am not casting if you wants to cast then for `int (*p)[4]` cast would be `p = (int(*)[4])malloc(4 * sizeof(int));` – Grijesh Chauhan Feb 12 '14 at 14:09
  • I know these. What I am asking is for `int (*p)[4]; p = malloc(4 * sizeof(int));` the value of `p` and `*p` are same. So why not use `int *p; p = malloc(4 * sizeof(int));`? And also how do you declare `p` such that `p` points to an array of 4 integers and `p+1` also point to another array of 4 integers? – HelloWorld123456789 Feb 12 '14 at 14:16
  • @RikayanBandyopadhyay value wise same but *semantically* of `p` and `*p` are different when you declares `p` as `int (*p)[4]` To observe the difference try to print `p` and `p + 1` and `*p` and `*p + 1`. Now of-course `nt *p; p = malloc(4 * sizeof(int))` is state forward approach. I just answered to OP how to use `int (*p)[4]` with dynamically allocate memory. – Grijesh Chauhan Feb 12 '14 at 14:22
  • @RikayanBandyopadhyay Remember when you decelerates `int a[4]` then `&a` is of `int (*)[4]` but not `int*`. May be that is the reason how to use `int (*)[4]` type pointer for dynamic memory allocation. – Grijesh Chauhan Feb 12 '14 at 14:25
0

If you are just allocating a 4-element array of int, you'd write

int (*p)[4] = malloc( sizeof *p );

or

int (*p)[4];
...
p = malloc( sizeof *p );

Since the type of p is "pointer to 4-element array of int", the type of the expression *p is "4-element array of int", so sizeof *p gives us the right number of bytes to allocate (sizeof (int [4])).

You'd access each element as

(*p)[i] = x; 

The parentheses are necessary. Remember that the type of the expression *p is "4-element array of int", so we want to apply the [] operator to the result of that expression. Since [] has higher precedence than unary *, we need to explicitly group the * operator to p with the parentheses.

You could also write p[0][i] = x, since p[0] is synonymous with *p. This gets rid of the explicit dereference, but it treats p as a 2D array, which may be confusing.

Because of that confusion, this isn't the usual way of allocating a 1D array; the usual practice is to write

int *p = malloc( n * sizeof *p );
...
p[i] = x;

Since the type of p is "pointer to int", the type of the expression *p is simply int, so we need to specify the number of ints we want in the malloc call. Since p is a simple pointer to int, we can apply the subscript operator to it directly without having to dereference it first.

If you're allocating an Nx4-element array of int, you'd write

int (*p)[4] = malloc ( N * sizeof *p );

and you'd access each element as

p[i][j] = x;

Since the type of the expression p is "pointer to 4-element array of int", the type of the expression p[i] is "4-element array of int", thus we don't need to explicitly dereference p.

So, to sum up:

  • Allocating and using a single element of type T:
        T *p = malloc( sizeof *p );
        *p = ...;
        free( p );
  • Allocating and using a 1D array of T:
        T *p = malloc( N * sizeof *p );
        p[i] = ...;
        free( p );
  • Allocating and using a 2D array of T:
        T (*p)[N] = malloc ( M * sizeof *p );
        p[i][j] = ...;
        free( p );
  • Allocating and using a 3D array of T:
        T (*p)[M][N] = malloc (K * sizeof *p );
        p[i][j][k] = ...;
        free( p );

The pattern for higher-dimension arrays should be clear.

John Bode
  • 119,563
  • 19
  • 122
  • 198