gpt4 book ai didi

c - C 中函数返回局部变量地址时的 NULL 行为

转载 作者:行者123 更新时间:2023-12-02 02:39:19 25 4
gpt4 key购买 nike

我有以下 C 代码:

#include <stdlib.h>
#include <stdio.h>

char* foo() {
char abc[4] = "abc";
return abc;
}

int main() {
printf("%s", foo());
return 0;
}

如果我用 gcc 编译它并运行可执行文件,我会得到 (null)% 作为输出。

如果我运行稍微修改过的代码:

#include <stdlib.h>
#include <stdio.h>

char* foo() {
char abc[4] = "abc";
return abc;
}

int main() {
printf("%c", *(foo()));
return 0;
}

我遇到了段错误。

我的问题是:为什么我的第一个代码不会出现段错误?我正在运行Linux和gcc版本:gcc (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0

这两个代码在编译时都会生成一个警告:函数返回局部变量的地址[-Wreturn-local-addr]警告

最佳答案

return abc;开始执行时,abc是一个指向foo内部定义的数组的指针。 (正式地,它指定数组本身,但它会自动转换为第一个元素的地址。)该函数将返回此指针值。但是,当函数执行结束时,数组的生命周期也结束。

根据 C 2018 6.2.4 2:

The value of a pointer becomes indeterminate when the object it points to (or just past) reaches the end of its lifetime.

当 C 中的值不确定时,它的行为可能就像具有任何值一样,包括每次尝试使用它时都具有不同的值或具有陷阱值 (C 2018 3.19. 2和3.19.3)。请注意,这不仅意味着指针值指向的内容是不确定的;还意味着指针值指向的内容是不确定的。 指针本身的值是不确定的。

因此,即使 abc 在内存中有某个地址(例如 100400),也不意味着 100400 返回给调用者。返回给调用者的是不确定的:它可以是任何值,包括空指针值。

编译器的优化器似乎已通过提供或允许空指针值作为函数 foo 的返回值来响应代码中未定义的行为。这是 C 标准所允许的。

当您将此空指针传递给 printf 以便与 %s 一起使用时,您的 printf 实现检查了该指针,发现它是一个空值指针,并打印“(null)”,而不是尝试使用它来访问内存中的字符串。

当您尝试使用*(foo())取消引用指针时,没有对指针值进行初步检查。程序的机器代码尝试使用空指针访问内存,这导致了段错误。

关于c - C 中函数返回局部变量地址时的 NULL 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63861706/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com