gpt4 book ai didi

c - 初始化局部变量,什么时候发生?

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

我刚刚了解了 C 中的局部变量,一本书说当具有局部变量的函数结束时,局部变量总是从内存中初始化自身。所以我只是写了一些代码(使用 Visual Studio 2015)来确认这一点。这是代码:

#include <stdio.h>
int* poin2 = NULL;
void fuc(void);

int main(void) {
int a = 3;

fuc();

printf("%d %d\n", a, *poin2);

return 0;
}

void fuc(void)
{
int a = 2;
poin2 = &a;
}

一开始我以为会显示3和一个垃圾号,因为fuc结束了,a in fuc (not in main)必须在内存中初始化,所以poin2没有任何意义。但结果是:

3 2

为什么它没有从内存中删除?我测试了下一段代码以弄清楚:

#include <stdio.h>
int* poin2 = NULL;
void fuc(void);

int main(void) {
int a = 3;
int b = 1;
fuc();
while (1)
{
b++;
printf("%d %d\n", a, *poin2);
if (b > 5) break;
}

return 0;
}

void fuc(void)
{
int a = 2;
poin2 = &a;
}

我的想法是:初始化内存需要很短的时间,所以我想找个时间。结果:

3 2
3 -858993460
3 -858993460
3 -858993460
3 -858993460

我用更多的代码对其进行了测试,我发现它不会在具有局部变量的函数完成时发生变化,而只会在另一个函数完成时发生变化。(我的意思是它不会在 fuc() 完成时删除,它会在 printf 完成时删除, 并且它不依赖于函数是什么,不仅是 printf,还包括 scanf 或其他函数)

但是为什么?是我的代码有问题还是什么?

最佳答案

您可能知道,返回局部变量的地址然后尝试取消引用该地址是 undefined behavior .

这意味着您的程序可能会崩溃,可能会表现出奇怪的行为,或者看起来可以正常工作。对于相同的代码或存在看似无关的更改,此行为不需要从一个编译器到下一个编译器保持一致。

也就是说,许多编译器通常不会在函数返回后修改函数使用的堆栈部分。这是通常不需要的额外工作。所以在 fuc 返回后,它所拥有的局部变量仍然包含它们的旧值。

在调用 printf 时,指针 poin2 在调用 printf 之前被取消引用。由于在此之前没有调用其他函数,因此上次调用 funca 的值尚未被覆盖。因此,您读取了旧值。

当您在循环中调用 printf 时,第一次调用能够像以前一样获取 a 的值。但是,调用 printf 会修改堆栈。具体来说,存储 a 的内存位置被其他内容覆盖。因此,在随后调用 printf 时,它会读取最后一次调用 printf 时留在该内存位置的内容。

但是,重申一下,这是未定义的行为。并非所有编译器都需要以这种方式运行。例如,在高安全性环境中,编译器可能会在函数返回后清除堆栈内存,从而无法恢复该函数使用的敏感数据。

关于c - 初始化局部变量,什么时候发生?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40114489/

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