简体   繁体   中英

2d array using a double pointer and malloc function

i am trying to create a 2d array using double pointer... my code is...


int **p1;
p1=(int **) malloc(2*sizeof(int *));
for(int i=0;i<2;i++)
{
    p1[i]=(int *) malloc(3*sizeof(int));
    for(int j=0;j<3;j++)
    {
       scanf("%d",(p1+i)+j);
    }

}
for(int i=0;i<2;i++)
{

    for(int j=0;j<3;j++)
    {
       printf("%d\n",*(*(p1+i)+j));
    }

}

as i have declared a double pointer (**p1) for it and i am able to put data at all those places using my scan scanf("%d",(p1+i)+j); statement. And to dereference i can use print statement as i have done printf("%d\\n",*(*(p1+i)+j));

but why it is breaking during print statement but accepting my scan statement.

but why this is giving me correct response...

int mybox[][4]={{1,2,3,4},{5,6,7,8}};//we have to provide subscript;
for(int i=0;i<2;i++){
     for(int j=0;j<4;j++){
        printf("%d",mybox[i][j]);//will print all elements
        }
}
        printf("%d",*(*(mybox)+1));//give me 2
        printf("%d",*(*(mybox+1)+1));//give me 6
        printf("%d",*(*(mybox+1)+3));//give me 8

Your scanf portion is implemented incorrectly. It destroys your data. Ironically, the problem does not reveal itself during scanf phase, but instead causes a crash at printf stage.

The correct scanf code might look as follows

for(int i=0;i<2;i++)
{
    p1[i]=(int *) malloc(3*sizeof(int));
    for(int j=0;j<3;j++)
    {
       scanf("%d",*(p1+i)+j);
    }
}

Note the extra * . What you really need here is

scanf("%d", &(*(*(p1 + i)) + j));

You can write it this way if you want. But you can notice that the outer & "annihilates" with the next nested * , so the above is equivalent to

scanf("%d", *(p1 + i) + j);

However, my advice to you is to stop using the barely-readable *-and-+ combination for array element access and start using the [] instead. This is how your code should have looked from the very beginning

...
scanf("%d", &p1[i][j]);
...
printf("%d\n", p1[i][j]);

On top of that, since this is taggged C, avoid using sizeof with types as much as possible and stop casting the result of malloc . A better variant would be

int **p1;

p1 = malloc(2 * sizeof *p1);
for(int i = 0; i<2; i++)
{
  p1[i] = malloc(3 * sizeof *p1[i]);
  ...   
scanf("%d",(p1+i)+j);

This is wrong, and not what you expect. Associativity says that a+b+c == (a+b) + c == a + (b+c).

Avoid direct pointer arithmetic because it is hell confusing when you are new to the language. Prefer:

   scanf("%d", &p1[i][j]);

   printf("%d\n", p1[i][j]);

The generated assembly code is exactly the same as if you went for direct pointer arithmetic.

Also, unrelated but important, do not cast the return type of malloc(), as this may hide potential bugs in your code (like the lack of a #include <stdlib.h> , which is very important).


Keep in mind that the types int** and int[][N] are quite different in their implementation. Assumptions made for one are not true for the other, even though you can access the elements using the same var[i][j] syntax.

Your second example gives the correct answer because it is... correct? That is it. The second example doesn't have any scanf(), which is where your problem is in the first example.

scanf("%d\n",(*(p1+i)+j));

替换您的scanf以获取数组值...

This creates a 2d array where all data is stored in adjacent memory cells on the heap (as opposed to the ** syntax more commonly seen). It uses the concept of array pointers which you can read about in the C lang FAQ .

int (*ptr)[X]; 
ptr = malloc(X * Y * sizeof(int));

And yes, you can use the ptr[x][y] if you malloc in this way.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM