我正在自学指点,对人生有怀疑,看看这个例子:
int* fun(){
int arr[10];
for(size_t c = 0;c<10;c++){
arr[c] = c + 10;
}
return arr;
}
int main() {
int* p;
p = fun();
printf("%p",p);
}
这个例子显然会打印一个空地址,因为数组在函数结束后被释放了。为了解决这个问题,我尝试了malloc,它起作用了。
成功之后我尝试了另一种代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
int* fun(){
int arr[10];
for(size_t c = 0;c<10;c++){
arr[c] = c + 10;
}
int* arr2 = arr;
return arr2;
}
int main() {
int* p;
p = fun();
printf("%p",p);
}
根据我的研究,这个例子应该再次打印一个空地址,但是它和malloc解决方案一样好用。我不明白为什么会发生这种情况。如果int arr[10]
被释放,它的指针应该指向null,对吗?
1条答案
按热度按时间wgmfuz8q1#
这个例子显然将打印一个空地址
不可以。函数返回的地址是 indeterminate,这意味着它没有确定的值。很可能它和
arr
原来的地址是一样的,但是编译器可以随意打印任何东西,或者把整个东西当作一个“陷阱表示”,这意味着当这种情况发生时,它可能会抛出异常/信号等。当我在gcc中运行你的代码时,它决定打印“(nil)”输出,而clang认为“明显的”结果应该是
0x7ffef0b3c870
,程序也可以打印0xDEADBEEF
,这也是符合的。根据我的研究,这个示例应该再次打印空地址
你的研究是建立在错误的结论上的。你看到一辆汽车相撞,它倒着着陆,然后得出结论,当汽车相撞时,它们总是倒着着陆。
在您的两个示例中,返回指针的值都是不确定的。
来源
C17第6.2.4/2节:
如果一个对象在它的生存期之外被引用,那么它的行为是未定义的。当它所指向的对象(或者刚刚过去的对象)到达它的生存期结束时,指针的值就变得不确定了。
C17第3.19.2节:
不确定值
未指定的值或陷阱表示