gpt4 book ai didi

C 堆栈分配的字符串作用域

转载 作者:太空宇宙 更新时间:2023-11-04 02:08:23 25 4
gpt4 key购买 nike

对于直接的 C 和 GCC,为什么指向的字符串在这里没有被破坏?

#include <stdio.h>

int main(int argc, char *argv[])
{
char* str_ptr = NULL;

{
//local to this scope-block
char str[4]={0};
sprintf(str, "AGH");

str_ptr = str;
}

printf("str_ptr: %s\n", str_ptr);

getchar();
return 0;
}

|----输出-----|

str_ptr: AGH

|--------------------|

这是 a link使用在线编译器编译和执行上述代码。

我知道如果 str 是字符串文字,str 将存储在 bss 中(本质上是静态的),但是 sprintf(ing) 到堆栈-分配的缓冲区,我认为字符串缓冲区将是纯粹基于堆栈的(因此地址在离开范围 block 后毫无意义)?我知道可能需要额外的堆栈分配来覆盖给定地址处的内存,但即使在发生堆栈溢出之前使用递归函数,我也无法破坏 str_ptr 指向的字符串>.

仅供引用,我正在 VS2008 C 项目中进行测试,尽管 GCC 似乎表现出相同的行为。

最佳答案

虽然鼻蜥蜴是 C 民间传说的一个流行部分,但其行为未定义的代码实际上可以表现出任何行为,包括神奇地复苏其生命周期已过期的变量。具有未定义行为的代码可能看起来“有效”这一事实既不应令人惊讶,也不应成为忽视纠正它的借口。一般来说,除非您从事编写编译器的工作,否则在任何给定环境中检查未定义行为的确切性质并不是很有用,尤其是当您眨眼之后它可能会有所不同。

在这种特殊情况下,解释很简单,但它仍然是未定义的行为,因此根本不能依赖以下解释。它可能随时被爬行动物排放物取代。

一般来说,C 编译器会使每个函数的堆栈帧具有固定大小,而不是随着控制流进入和离开内部 block 而扩展和收缩。除非被调用的函数是内联的,否则它们的栈帧不会与调用者的栈帧重叠。

因此,在某些具有特定编译选项集的 C 编译器中,除了特定的月相之外,字符数组 str 不会被调用 printf,即使变量的生命周期已过期。

关于C 堆栈分配的字符串作用域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17984314/

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