理解C中的简单指针

时间:2013-05-18 23:10:28

标签: c pointers

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 个答案:

答案 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)

  • 当我删除行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

输出不会改变。