存储在全局链表中的本地结构(并在其他函数中访问)适用于 VC2010。这是正确的 C99/ANSI 吗?

发布于 2024-10-25 03:04:22 字数 1143 浏览 5 评论 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 中没有传递引用的后果。如果可以像这样使用结构数据,那么数据什么时候会得到释放了?

谢谢!

The following code works fine:


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;
}

The struct is created locally in a function other than main, yet I was able to retrieve the data from the linked list outside of the scope of localstructtest(). Local variables are created on the stack, is this true with this struct as well? Or is it actually created on the heap and the pointer/reference remains valid? I expected this to fail horribly when I tested it. I'll admit that I am a C++ programmer and I probably don't completely understand the ramifications of there being no pass-by-reference in C. If it is OK to use the struct data like this, when does the data ever get freed?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

清风挽心 2024-11-01 03:04:22

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

说真的:这可能在一个小示例程序中有效,但随着程序的增长,它肯定会在你面前爆炸。

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

Undefined behavior. It may work, it may not, it may turn your computer into a warthog, all depending on the phase of the moon.

Seriously: this may work in a small example program, but it's sure to blow up in your face as the program grows.

As for pass-by-reference: in C you'd do that by passing a pointer. The basic memory allocations rules are the same as in C++: a local struct is allocated on the stack and destroyed when it goes out of scope. The main difference is that there's never a destructor, so you can't get full RAII.

⊕婉儿 2024-11-01 03:04:22

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

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() 用零覆盖了堆栈上的结构。

The reason it works on most of the systems is that stack is not zeroed out when the frame is popped. If you make a small seemingly unrelated change to your program, it will stop working.

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;
}

This happens because junk() overwrites the structure on stack with zeros.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文