#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'之间有什么区别?
答案 0 :(得分:5)
在_pTest1
和_pTest2
函数中,您将返回局部变量a
的地址,其范围/生命仅在函数内。在函数外部访问变量a
是undefined 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