简体   繁体   English

了解二维数组的内存分配

[英]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是的结果mallocp[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.

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