0

以下代码工作正常:


typedef struct node_s {
    void *data;
    struct node_s *next;    
} NODE;

typedef struct test_s
{
    int asdf;
}TEST;
NODE *list_create(void *data)
{
    NODE *node;
    if(!(node=malloc(sizeof(NODE)))) return NULL;
    node->data=data;
    node->next=NULL;
    return node;
}

NODE *list_insert_after(NODE *node, void *data)
{
    NODE *newnode;
    newnode=list_create(data);
    newnode->next = node->next;
    node->next = newnode;
    return newnode;
}

NODE *list, *second, *third;

void localstructtest()
{
    TEST t;
    t.asdf = 10;

    third = list_insert_after(second, (void*)&t);
}

int main()
{
    TEST th;
    TEST* hrm;

    /* Create initial elements of list */
    list=list_create((void*)"First");
    second=list_insert_after(list, (void*)"Second");
    localstructtest();

    hrm = (TEST*)third->data;
    th = *hrm;
    return 1;
}

该结构是在除 main 之外的函数中本地创建的,但我能够从 localstructtest() 范围之外的链表中检索数据。局部变量是在堆栈上创建的,这个结构也是如此吗?或者它实际上是在堆上创建的并且指针/引用仍然有效?当我测试它时,我预计这会失败。我承认我是一名 C++ 程序员,我可能并不完全理解 C 中没有传递引用的后果。如果可以像这样使用结构数据,那么数据什么时候得到释放?

谢谢!

4

2 回答 2

2

未定义的行为。它可能有效,也可能无效,它可能会将您的计算机变成疣猪,这一切都取决于月

说真的:这可能在一个小示例程序中起作用,但随着程序的增长,它肯定会在你的脸上爆炸。

至于传递引用:在 C 中,您可以通过传递指针来做到这一点。基本的内存分配规则与 C++ 中的相同:本地struct在堆栈上分配并在超出范围时销毁。主要区别在于从来没有析构函数,因此您无法获得完整的 RAII。

于 2011-03-23T17:12:16.790 回答
1

它适用于大多数系统的原因是在弹出框架时堆栈不会清零。如果您对程序进行看似无关的小改动,它将停止工作。

int junk()
{
    char junkdata[100] = {0};
    return 42;
}

int main()
{
    TEST th;
    TEST* hrm;

    /* Create initial elements of list */
    list=list_create((void*)"First");
    second=list_insert_after(list, (void*)"Second");
    localstructtest();
    junk();

    hrm = (TEST*)third->data;
    th = *hrm;
    return 1;
}

发生这种情况是因为 junk() 用零覆盖了堆栈上的结构。

于 2011-03-23T17:22:29.590 回答