0

问题描述

各路大神,我直接上代码了。如下:

#include <stdio.h>

int *get() {
    int a = 1;
    int *p = &a;
    return p;
}

int main() {
    int *pptr;
    pptr = get();

    int *ptr = get();

    printf("%d\n", *ptr);
    printf("%d\n", *pptr);
}

clipboard.png

clipboard.png

如代码所示,ptr和pptr两个指针都是获取到get()返回的同一个地址。然而,打印出来的两个值却是不一样的。而且每次第二个值都是不一样的。是不是指针的地址移动了?请大神们指示一下,感激不尽!

Chenxj 81
2018-12-25 提问
5 个回答
2

已采纳

哈哈,这个问题猛一看有点弱智(不好意思哈),但是细看一下却有点意思。

首先就像楼上所说,ptr和pptr是两次函数调用时的局部变量地址,同一个局部变量两次调用所分配的地址未必相同,这个是肯定的。

但是!!两次连续调用同一个函数,所分配的栈帧却很有可能是一样的,道理很简单,应用程序的栈通常都是连续分配的,随着一层层调用逐步向下增长。所以前一个get函数调用完之后立即再调用一次,不出意外的话两次栈帧应该是一样的。这一点在题主调试的时候也多次重现了。

那么为什么两个地址相同的指针打印出来的值却不一样呢?答案是“你这两个指针是外部公共地址,谁规定它必须一样啊!!”

仔细看,谁最有可能修改了这个地址上的值?哈哈,不好意思,虽然隐藏的很好但还是被找到了,那就是printf!

第一次打印的时候,ptr的值在printf的栈帧分配前就先行取出来了,所以printf可以打印出1,但随着printf的运行,它覆盖掉了该地址上的值,后面再取值的时候就已经不是原值了。

题主可以交换一下两个打印语句,你会发现第一次打印总是对的,第二次就错了,跟打印的是ptr还是pptr无关。

所以,明白了原理,以后就知道为什么不能这么用了。

1
回复 Chenxj

答主的意思就是printf函数调用时也使用了前面get函数使用过的栈,因此修改了原先使用的a变量,你可以尝试在调用第一个printf前,再调用一次printf(随便打印一个具体的值),那后面的两次打印应该就一样了,但是结果应该都不为1

春光灿烂朱八戒 · 2018年12月26日

展开评论
1

ptrpptr实际上都是指的函数geta的地址,a是函数内的局部变量,每次执行都会重新分配栈,肯定地址不一样。

0

同一个函数运行了两次,里面的变量地址怎么会一样呢 不是变量名一样地址就非要一样吧

0

main函数中的pptr和ptr都指向了函数get函数中的局部变量的地址,而get中的局部变量在函数结束时就释放掉了,即main中的指针指向的已释放的地址,取其中的值的操作行为是未定义的,结果是随机的

0

重复运行了 同一个函数

撰写答案

推广链接