[英]Understanding memory allocation for a 2D like array
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.我知道p[0]
和p[1]
指向同一件事,如果p[1]
有它自己的 malloc, p[0][0]
将导致 0 但它导致 1。
I'm trying to understand what is causing it to result in 1. So the result of this code is:我试图了解导致 1 的原因。所以这段代码的结果是:
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;
}
Let q
be the result of the malloc
in p[0] = (int *)malloc(2 * sizeof(int));
让q
是的结果malloc
在p[0] = (int *)malloc(2 * sizeof(int));
. .
Then, after that assignment and p[1] = p[0];
然后,在赋值之后p[1] = p[0];
, both p[0]
and p[1]
are q
. , p[0]
和p[1]
都是q
。
Then the statement p[i][j] = i + j;
然后语句p[i][j] = i + j;
is equivalent to q[j] = i+j;
等价于q[j] = i+j;
, regardless of whether i
is 0 or 1. ,无论i
是 0 还是 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:当i
为 0 时执行两个赋值:
q[0] = 0 + 0;
q[1] = 0 + 1;
and two assignments when i
is 1:以及当i
为 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.后两个覆盖前两个,所以结果是q[0]
包含 1, q[1]
包含 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.所以它打印 1、2、1 和 2。
Both values are set twice , once through p[0][j]
and the second time through p[1][j]
.这两个值都设置了两次,一次通过p[0][j]
,第二次通过p[1][j]
。 Since second time i
is 1, the values put into those cells are 1 + j
.由于第二次i
为 1,因此放入这些单元格中的值为1 + j
。
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.我还应该注意,强制转换malloc
返回是没有必要的。
The pointer p[1]
is set to the value of the pointer p[0]
指针p[1]
被设置为指针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 循环
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.首先使用指针p[0]
,然后使用指向同一数组的指针p[1]
。 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]
.因此可以完全忽略外循环的第一次迭代,因为在外循环的第二次迭代中,使用指针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)因此p[1][0]
被设置为1 + 0
即为1
(在循环的第一次迭代中)并且p[1][1]
被设置为1 + 1
即为2
(在第二次迭代中)循环)
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
的这些调用中,使用指向同一数组的指针p[0]
和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]);
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]);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.