0
int main()
{
    int *p1,*p2;
    int a;
    p1=(int *)malloc(sizeof(int));
    p2=(int *)malloc(sizeof(int));
    p1=&a;
    p2=p1;
    a=10;
    printf("\n%d\n",*p1);
    printf("\n%d\n",*p2);
    printf("\n%d\n",a);
    return 0;
}

当我删除行p1=(int *)malloc(sizeof(int));并且p2=(int *)malloc(sizeof(int)); 输出没有改变时。你能解释一下为什么吗?

4

4 回答 4

10
p1 = &a 

这只是丢掉了你的第一个 malloc 行的结果,第一个 malloc 是没有意义的。

p2 = p1

对 p2 做同样的事情。

p1 和 p2 的指针空间是在堆栈上分配的,因此您可以为它们分配任何您想要的空间,而无需额外的内存。如果您想为它们分配一个尚未在其他地方分配内存的整数,则只需要 malloc 。

它们都指向在堆栈上分配的内存a,现在您在堆上分配的内存已泄漏,无法恢复或释放。您可以看到这是真的,因为当您将 a 设置为 10 时,所有三个打印行都会打印 10。

因此,程序只有在没有这两条 malloc 行的情况下才是正确的。

于 2013-05-18T23:13:34.050 回答
1

两个 malloc 语句为存储两个整数分配内存,并将它们的地址(指针)分别分配给 p1 和 p2。所以在这行之后:

p1=(int *)malloc(sizeof(int));
p2=(int *)malloc(sizeof(int));

p1 和 p2 指向刚刚由 malloc 分配的两个不同的内存位置。

该行:

p1=&a;

将整数 a 的地址分配给 p1,因此 p1 不再指向新分配的内存。相反,它指向整数 a。

该行:

p2=p1;

将 p1 中的内容赋值给 p2,因为 p1 包含 a 的地址,p2 在这一行之后也包含整数 a 的地址。此时p1、p2都指向整数a。

该行:

a=10;

将值 10 赋值给整数 a。因为 p1 和 p2 都指向整数 a,所以 *p1、*p2 和整数 a 的结果应该都是 10。

malloc 之前分配的内存会导致内存泄漏,因为没有指向它们的指针,因此无法释放它们。删除这两行不会影响结果,因为在这行之后:

p1=&a;
p2=p1;

他们成为孤儿,内存泄露。

于 2013-05-18T23:30:03.863 回答
0

问题:“当我删除 p1=(int *)malloc(sizeof(int)); 和 p2=(int *)malloc(sizeof(int)); 行时,输出没有改变。你能解释一下原因吗? "

答:因为您不再使用分配给 p1 和 p2 的内存,因为您将 a 的地址分配给 p1,然后将现在存储在 p1 中的地址分配给 p2

也许在代码中解释得更好

int main()
{
    int *p1,*p2;                     // define two pointers to int
    int a;                           // define an int variable (space for an int in memory must be reserved)
    p1=(int *)malloc(sizeof(int));   // get memory large enough for an int. (int *) makes the default return value of pointer to void a pointer to int
    p2=(int *)malloc(sizeof(int));   // same thing but for the other point
    p1=&a;                           // overwrite p1 and puts in it the address used for integer variable a
    p2=p1;                           // overwrite p2 with what p1 has and that is the address of integer variable a
    a=10;                            // now put where the integer variable a has its address the value 10 to
    printf("\n%d\n",*p1);            // output what p1 points to (and it points to address of integer variable a)
    printf("\n%d\n",*p2);            // same for p2
    printf("\n%d\n",a);              // just output a
    return 0;
}

跟踪变量

int main()
{
    int *p1,*p2;
    int a;                           // &a = 0xDDDDDDDD
    p1=(int *)malloc(sizeof(int));   // p1 = 0xAAAAAAAA
    p2=(int *)malloc(sizeof(int));   // p2 = 0xAAAAAAAD
    p1=&a;                           // p1 = 0xDDDDDDDD 
    p2=p1;                           // p2 = 0xDDDDDDDD 
    a=10;                            // a=10 (at address 0xDDDDDDDD)
    printf("\n%d\n",*p1);            
    printf("\n%d\n",*p2);
    printf("\n%d\n",a);
    return 0;
}

关于如何获取地址的地址的附加说明a。这是一个自动变量,在输入函数时创建并在退出时丢弃。因此,虽然a只是声明并且没有分配任何内容,但仍为其分配了内存。

引自 K&R 附录 A

A4.1 存储类

.. 自动对象是块的本地对象,并在退出块时被丢弃。块内的声明创建自动对象...

于 2013-05-18T23:28:29.517 回答
0
  • 当我删除行 p1=(int *)malloc(sizeof(int)); 和 p2=(int *)malloc(sizeof(int)); 输出不变。你能解释一下为什么吗?

xaxxon 已经给出了正确的答案,但这里是我的替代解释。

假设 p1 和 p2 不是指针。然后您的代码如下所示:

int p1,p2;
int a;
p1=6354; // some number (because malloc returns some number)
p2=6376; // some number
p1=a;
p2=p1;

如果删除行

p1=6354; // some number
p2=6376; // some number

输出不变。

于 2013-05-18T23:28:44.440 回答