有人可以向我解释为什么输出以下代码6而不是5?我不明白如何调用hoo改变了m-> x的值。 即使在运行代码并遵循它的每一步之后,我仍然不清楚。
#include <stdio.h>
#include <stdlib.h>
typedef struct a {
int x;
struct a* next;
}a_t;
a_t* foo() {
a_t* varp, var = { 5,NULL };
varp = &var;
return varp;
}
a_t* hoo() {
a_t* varp, var = { 6,NULL };
varp = &var;
return varp;
}
void main()
{
a_t* m = foo();
hoo();
printf("%d", m->x);
}
答案 0 :(得分:2)
您的函数a
和hoo
返回指向局部变量的指针,根据定义*未定义的行为`。
它们都实现了不同的结构(2个副本),并且您从第一个开始打印价值。
由于你首先在函数foo
的堆栈上创建了结构,所以你很幸运,函数foo
也在同一个地方的堆栈上创建了函数。
因此你有覆盖。
如果要从函数返回指针,请使用hoo
或使用static
在堆上动态分配内存。
malloc
现在您正在堆栈外部分配内存,它将按预期工作。
答案 1 :(得分:2)
您的代码有未定义的行为。让我们看看为什么。
a_t* foo() {
// creates a variable on the stack
a_t* varp, var = { 5,NULL };
// sets address of variable on stack to another variable on the stack
varp = &var;
// you return that address on the stack
return varp;
}
a_t* hoo() {
// creates a variable on the stack
a_t* varp, var = { 6,NULL };
// sets address of variable on stack to another variable on the stack
varp = &var;
// you return that address on the stack
return varp;
}
为什么以上代码导致undefined behavior?在函数调用hoo
和foo
结束后,您将返回不再拥有的变量(包含地址)。
系统现在拥有那个内存!
计算机是愚蠢的,会盲目执行你给他们的任何命令。我认为您打算使用malloc来保存您希望在函数调用之外保留的变量。
a_t* foo() {
a_t *varp = malloc(sizeof(struct a_t));
varp->x = 5;
varp->next = NULL;
return varp;
}
你能修复另一个吗?
答案 2 :(得分:2)
基本上,当你调用hoo()时,你创建了一个不同的varp和var,而不是你在使用foo之前创建的varp和var并将它存储在变量m中。但是,这个新的varp在与m的varp相同的内存地址上创建并覆盖其值。
如果你使用F5逐行进行并在main中的行上添加3个断点,则在变量m上添加一个监视,然后进入hoo()并注意分配给varp的内存地址与指定为varp的内存地址相同m ...所以当你离开hoo()并返回main时,你将失去存储在m中的值,因为它被覆盖notice the cursor is still at line 22 and didn't overwrite yet
答案 3 :(得分:0)
您可以定义“static var ...”。 因此函数返回后var将仍然存在。