繁体   English   中英

了解C语言中的简单指针

[英]Understanding simple pointers in C

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)); 输出不变。 你能解释为什么吗?

p1 = &a 

那只会丢掉第一个malloc行的结果,第一个malloc是没有意义的。

p2 = p1

对于p2完全相同。

p1和p2的POINTERS的空间是在堆栈上分配的,因此您可以将所有所需的空间分配给它们,而无需额外的内存。 如果要为它们分配一个尚未在其他地方分配其内存的整数,则仅需要malloc。

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

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

两个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;

它们成为孤立的,泄漏的内存。

问题:“当我删除行p1 =(int *)malloc(sizeof(int));和p2 =(int *)malloc(sizeof(int));输出不会改变。您能解释一下原因吗? ”

答:因为您不再使用分配给p1和p2的内存,因为您已将p的地址分配给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储存等级

..自动对象位于块的本地,在退出块时将其丢弃。 块内的声明创建自动对象...

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

输出不变。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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