【发布时间】:2016-04-12 00:12:43
【问题描述】:
这是我的编程语言概念/实现课程的问题。给定以下C代码sn-p:
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 的分配不应该对 我?我的想法是编译器正在玩一些优化该子例程调用的游戏,有人可以澄清一下吗?
【问题讨论】:
-
你被问到的确切问题是什么?
foo()中的i无法从其他地方初始化,除非通过某种软糖使未定义的行为看起来像您认为它应该具有。在 C 中,i不会在 任何 系统上初始化,当然也不会在 大多数 上初始化。 -
@WeatherVane 问题的确切措辞是:考虑以下 C 程序:[代码块如上] 子例程 foo 中的局部变量 i 从未初始化。然而,在许多系统上,变量 i 似乎在对 foo 的调用之间“记住”了它的值,并且程序将打印 0 1 2 3 4 5 6 7 8 9。 (a) 建议对此行为的解释。 (b) 更改上面的代码(不修改函数 foo)来改变这种行为。
-
我的测试不打印
0到9。这是未定义的行为。因此,您所能做的就是将其更改为另一种未定义的行为。它与malloc无关,与在调用foo时覆盖存储i的堆栈位置有关。 -
这就是我所害怕的,对于家庭作业来说,这不是一个构思非常好的问题。对于未定义的行为,我只在我的机器上使用 gcc 对其进行了测试,它确实打印了 0-9。无论如何,谢谢你
标签: c memory-management malloc programming-languages compiler-optimization