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));
时
输出没有变化。你能解释一下原因吗?
答案 0 :(得分:10)
p1 = &a
这只是抛弃你的第一个malloc线的结果,第一个malloc毫无意义。
p2 = p1
对p2完全一样。
p1和p2的POINTERS空间被分配在堆栈中,因此您可以在没有额外内存的情况下为其分配所有内容。如果你想为它们分配一个没有在其他地方分配内存的整数,你只需要malloc。
它们都指向堆栈上分配的内存,现在你在堆上分配的内存被泄露,无法恢复或释放。您可以看到这是真的,因为当您将a设置为10时,所有三条打印行都打印10。
因此,程序只有在没有这两个malloc行的情况下才是正确的。
答案 1 :(得分: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;
他们变成了孤儿,泄露了记忆。
答案 2 :(得分:0)
问题:“当我删除行p1 =(int *)malloc(sizeof(int));和p2 =(int *)malloc(sizeof(int));输出没有改变。你能不能请解释原因?“
答案:因为您不再使用分配给p1和p2的内存,因为您为p1分配了a的地址,然后将p2分配给现在存储在p1中的地址
也许在代码中更好地解释
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存储类
..自动对象是块的本地对象,在从块退出时被丢弃。块内的声明会创建自动对象...
答案 3 :(得分:0)
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
输出不会改变。