Reputation:
I'm trying to understand what is happening when the code is printed.
I know that p[0]
and p[1]
are pointing to the same thing and if p[1]
had it's own malloc, p[0][0]
would result in 0 but it's resulting in 1.
I'm trying to understand what is causing it to result in 1. So the result of this code is:
1
2
1
2
But I'm not sure how.
The code:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
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\n",p[0][0]);
printf("%d\n",p[0][1]);
printf("%d\n",p[1][0]);
printf("%d\n",p[1][1]);
return 0;
}
Upvotes: 1
Views: 84
Reputation: 23802
Code explained with comments:
// allocating space for 2 pointers to int
// this emulates an array of pointers to int *p[2]
int **p = malloc(2 * sizeof(int *));
// allocating space for the first pointer, which will contain 2 ints
p[0] = malloc(2 * sizeof(int));
// assigning the pointer p[0] or p + 0 to the pointer p[1] or p + 1
// both pointer are now pointing to the same memory location as you already established
// so there is no need to allocate memory for p[1] as it's already
// pointing to a valid memory location
p[1] = p[0];
// assigning the values, there is a redundancy here the values are assigned twice
// albeit different, 0 1 in the first iteration and rewritten in the second 1 2
for (i = 0; i < 2; i++)
for (j = 0; j < 2; j++)
p[i][j] = i + j;
// the same result could be achieved, with half of the iterations
// as both pointers point to the same location
for (i = 1; i < 2; i++) //i = 1
for (j = 0; j < 2; j++)
p[i][j] = i + j;
// printing the values, note that these are the same values from the same location
// but retrieved with different pointers p[0] and p[1]
printf("%d\n", p[0][0]);
printf("%d\n", p[0][1]);
printf("%d\n", p[1][0]);
printf("%d\n", p[1][1]);
I should also note that casting malloc
return is not necessary.
Upvotes: 0
Reputation: 310980
The pointer p[1]
is set to the value of the pointer p[0]
p[1] = p[0];
So the both pointers point to the same array with two elements due to this dynamic memory allocation
p[0] = (int *)malloc(2 * sizeof(int));
The outer for loop in these loops
for(i = 0; i < 2; i++)
for(j = 0; j < 2; j++)
p[i][j] = i + j;
at first uses the pointer p[0]
and then the pointer p[1]
that points to the same array. So the first iteration of the outer loop can be entirely ignored because in the second iteration of the outer loop the pointed array is overwritten using the pointer p[1]
. So the loops can be rewritten using only one loop
for( j = 0; j < 2; j++)
p[1][j] = 1 + j;
Thus p[1][0]
is set to 1 + 0
that is to 1
(in the first iteration of the loop) and p[1][1]
is set to 1 + 1
that is to 2
(in the second iteration of the loop)
In these calls of printf
the same array is outputted two times using the pointers p[0]
and p[1]
that point to the same array.
printf("%d\n",p[0][0]);
printf("%d\n",p[0][1]);
printf("%d\n",p[1][0]);
printf("%d\n",p[1][1]);
These calls are equivalent to calls either like
printf("%d\n",p[0][0]);
printf("%d\n",p[0][1]);
printf("%d\n",p[0][0]);
printf("%d\n",p[0][1]);
or like
printf("%d\n",p[1][0]);
printf("%d\n",p[1][1]);
printf("%d\n",p[1][0]);
printf("%d\n",p[1][1]);
Upvotes: 0
Reputation: 133919
Both values are set twice, once through p[0][j]
and the second time through p[1][j]
. Since second time i
is 1, the values put into those cells are 1 + j
.
Upvotes: 2
Reputation: 222660
Let q
be the result of the malloc
in p[0] = (int *)malloc(2 * sizeof(int));
.
Then, after that assignment and p[1] = p[0];
, both p[0]
and p[1]
are q
.
Then the statement p[i][j] = i + j;
is equivalent to q[j] = i+j;
, regardless of whether i
is 0 or 1.
Then these loops:
for(i = 0; i < 2; i++)
for(j = 0; j < 2; j++)
p[i][j] = i + j;
perform two assignments when i
is 0:
q[0] = 0 + 0;
q[1] = 0 + 1;
and two assignments when i
is 1:
q[0] = 1 + 0;
q[1] = 1 + 1;
The latter two overwrite the first two, so the result is q[0]
contains 1 and q[1]
contains 2.
Then this code:
printf("%d\n",p[0][0]);
printf("%d\n",p[0][1]);
printf("%d\n",p[1][0]);
printf("%d\n",p[1][1]);
is equivalent to:
printf("%d\n",q[0]);
printf("%d\n",q[1]);
printf("%d\n",q[0]);
printf("%d\n",q[1]);
so it prints 1, 2, 1, and 2.
Upvotes: 3