结构和指针。产量不清楚

时间:2017-07-15 13:11:01

标签: c

有人可以向我解释为什么输出以下代码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);
}

4 个答案:

答案 0 :(得分:2)

您的函数ahoo返回指向局部变量的指针,根据定义*未定义的行为`。

它们都实现了不同的结构(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?在函数调用hoofoo结束后,您将返回不再拥有的变量(包含地址)。 系统现在拥有那个内存! 计算机是愚蠢的,会盲目执行你给他们的任何命令。我认为您打算使用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将仍然存在。