0

I have the below program in C. How did p[0][0] become 1? Can somebody help in understanding?

#include <stdio.h>
#include<stdlib.h>

main()
{
  int i,j;
int **p=(int **)malloc(2 * sizeof(int *));
  p[0]=(int*) malloc(2*sizeof(int));
  p[1]=p[0];
  for(i=0;i<2;i++)
    for(j=0;j<2;j++)
     {
            p[i][j]=i+j;
            printf("%d,%d,%d",i,j,p[i][j]);
            printf("\n");
     }
 printf("%d,%d,%d",i,j,p[0][0]);
}

the output is as below

0,0,0
0,1,1
1,0,1
1,1,2
2,2,1
MikeCAT
  • 73,922
  • 11
  • 45
  • 70
  • 4
    Note that casting results of `malloc()` family is [considered as a bad practice](https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc). – MikeCAT Jun 11 '21 at 15:58
  • 1
    You allocate 2-pointers, now you must allocate a block of 2-int for each pointer... – David C. Rankin Jun 11 '21 at 16:21
  • 1
    `p[1]` is `p[0]`, so when you made the assignment `p[1][0] = 1`, that was equivalent to `p[0][0] = 1`. – William Pursell Jun 11 '21 at 17:53
  • OT: regarding: `main()` In C, there are only two valid signatures for `main()` They are: `int main( void )` and `int main( int argc, char *argv[] )` – user3629249 Jun 12 '21 at 13:32
  • OT: for ease of readability and understanding, please consistently indent the code. Indent after every opening brace '{'. Unindent before every closing brace '}'. Suggest each indent level be 4 spaces. – user3629249 Jun 12 '21 at 13:36

2 Answers2

3

The same pointer is assigned to p[0] and p[1]. This means p[0] and p[1] points at the same array. Therefore updates done via p[1] is also visible via p[0].

In the second iteration of outer for loop, 1 is assigned to p[1][0]. This makes p[0][0] to be 1.

MikeCAT
  • 73,922
  • 11
  • 45
  • 70
1

After the following lines of code:

int **p=(int **)malloc(2 * sizeof(int *));
p[0]=(int*) malloc(2*sizeof(int));
p[1]=p[0];

this is what you have in memory:

   int **        int *           int
   +---+         +---+           +---+
p: |   | ------> |   | p[0] -+-> |   | p[0][0], p[1][0]
   +---+         +---+       |   +---+
                 |   | p[1] -+   |   | p[0][1], p[1][1]
                 +---+           +---+

p[0] and p[1] point to the same 2-element array, so anything you write to p[0][i] is reflected in p[1][i] and vice-versa.

What you probably meant to do was something like

int **p = malloc( 2 * sizeof *p ); // cast not necessary, sizeof *p == sizeof (int *)
p[0] = malloc( 2 * sizeof *p[0] );
p[1] = malloc( 2 * sizeof *p[1] );

which would give you

   int **        int *            int 
   +---+         +---+            +---+
p: |   | ------> |   | p[0] ----> |   | p[0][0]
   +---+         +---+            +---+
                 |   | p[1] --+   |   | p[0][1]
                 +---+        |   +---+
                              |
                              |   +---+ 
                              +-> |   | p[1][0]
                                  +---+
                                  |   | p[1][1]
                                  +---+
John Bode
  • 119,563
  • 19
  • 122
  • 198