gpt4 book ai didi

c - Malloc 改变单独函数中未初始化变量的行为?

转载 作者:太空狗 更新时间:2023-10-29 16:01:06 25 4
gpt4 key购买 nike

这是我的 Programming Langs Concepts/Implementation 类(class)的问题。给定以下 C 代码片段:

void foo()  
{
int i;
printf("%d ", i++);
}
void main()
{
int j;
for (j = 1; j <= 10; j++)
foo();
}

foo 中的局部变量 i 从未被初始化,但在大多数系统上的行为类似于静态变量。这意味着程序将打印 0 1 2 3 4 5 6 7 8 9。我理解它为什么这样做(i 的内存位置永远不会改变)但是家庭作业中的问题要求修改代码(不改变 foo)以改变这种行为。我想出了一个有效的解决方案,使程序打印十个 0,但我不知道它是否是“正确”的解决方案,老实说,我也不知道为什么它有效。

这是我的解决方案:

void main()  
{
int j;
void* some_ptr = NULL;
for (j = 1; j <= 10; j++)
{
some_ptr = malloc(sizeof(void*));
foo();
free(some_ptr);
}
}

我最初的想法是 i 没有改变位置,因为在 foo 的调用周围没有发生其他内存操作,所以分配一个变量应该会破坏它, 但是由于 some_ptr 分配在堆中而 i 在堆栈上,some_ptr 的分配不应该对 ?我的想法是编译器正在玩一些优化子程序调用的游戏,有人可以澄清一下吗?

最佳答案

不可能有“正确”的解决方案。但是可以有一类适用于特定 CPU 架构、ABI、编译器和编译器选项的解决方案。

将代码更改为类似这样的内容会产生改变堆栈上方内存的效果,这种方式应该会以有针对性的方式影响许多(如果不是大多数)环境。

void foo()  
{
int i;
printf("%d ", i++);
}
void main()
{
int j;
int a [2];

for (j = 1; j <= 10; j++)
{
foo();
a [-5] = j * 100;
}
}

输出(Linux 上的 gcc x64):

0 100 200 300 400 500 600 700 800 900 

a[-5] 是用于跨越两个函数的开销和变量的堆栈字数。有返回地址,保存的堆栈链接值等。当 foo() 写入 a[-5] 时,堆栈可能看起来像这样:

i
saved stack link
return address
main's j
(must be something else)
main's a[]

我在第二次尝试时猜到了 -5。 -4 是我的第一个猜测。

关于c - Malloc 改变单独函数中未初始化变量的行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36561447/

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