关于C中关键字'return'的疑问

时间:2013-07-17 05:24:23

标签: c

#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'之间有什么区别?

2 个答案:

答案 0 :(得分:5)

_pTest1_pTest2函数中,您将返回局部变量a的地址,其范围/生命仅在函数内。在函数外部访问变量aundefined behavior

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

答案 1 :(得分: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