-1
#include <stdio.h>

int* _pTest1(void) {
    int a = 10;
    int *_pA = &a;
    return _pA;
}

int* _pTest2(int a){
    int* _pA = &a;
    return _pA;
}


int main()
{
    int* _pT = _pTest1();
    printf("%d\n", *_pT);

    _pT = _pTest2(20);
    printf("%d\n", *_pT);

    return 0;
}

输出:

1073831176
20

为什么第一个输出不是 10,而是 1073831176?func _pTest1 中的“return _pA”和 func _pTest2 中的“return _pA”有什么区别?

4

2 回答 2

5

在你的_pTest1_pTest2函数中,你都返回一个局部变量的地址,它的a作用域/生命只在函数内。a在函数外访问它的变量是未定义的行为

注意:在这两个函数a中都是本地函数(它们的内存来自堆栈)。

于 2013-07-17T05:26:39.070 回答
0

您将返回一个在函数终止时被清理的本地对象。

这是未定义的行为,任何事情都可能发生。

int _pTest1(void) {
    int a = 10; // a local object on the stack
    int *_pA = &a; // a local pointer to a local object on the stack
    return _pA;    // returning a local pointer to a local object, 
                   // wrong as the object pointed to may be cleaned up or overwritten.
}

此外,即使您的函数签名表明您想要返回一个整数,_pTest1 您也可能想要在返回指针的那一刻返回。*_pA

其实你可以尝试一个小实验。看看如果你返回_pA一个普通的指针 ( return _pA;) 或一个取消引用的指针 ( return *_pA;) 是否有任何区别。不要忘记更新函数签名和分配函数返回的类型。

您会发现在后一种情况下,输出将是一致的,而在前一种情况下,当您取消引用返回的地址时,该值可能早已不复存在。

在您的第二个函数中,您将返回一个指向该函数非本地参数的指针。然而a,在函数中仍然会有一个本地地址(因为 C 中的参数总是按值传递,并且会制作一个本地副本)。所以返回它仍然不能保证产生一个有意义的值。

您可以使用以下代码证明这一点:

int a = 55;
printf("%p\n", &a); // this will have one address e.g. 0xbff51148
int* _pT = _pTest2(a); // _pT points to an address where a local object was held, not reliable
printf("%p\n", _pT); // this will have another address e.g. 0xbff51130
于 2013-07-17T05:28:20.810 回答