【问题标题】:Assign memory to structure using structure使用结构将内存分配给结构
【发布时间】:2014-06-21 11:11:42
【问题描述】:

假设我有以下代码:

typedef struct _SingleList {
    struct _SingleList *link;
    int data;
} SingleList;


SingleList *prepend(SingleList *list, int data) {
    SingleList a;
    SingleList *newNode = &a; // Note, here I assign memory using structure not malloc.
    newNode->data = data;
    newNode->link = list;
    return newNode;
}

正如您在上面的 prepend 函数中看到的那样,我使用 a 地址而不是 malloc 分配内存,当我调用 prepend 函数时,它工作得很好。这是一个示例:

int main(void) {
    SingleList *list = NULL;
    list = prepend(list, 10);
    printf("%d", list->data);

    list = prepend(list, 20);
    printf("\n%d", list->link->data);

    list = prepend(list, 30);
    printf("\n%d", list->link->link->data);

}

那么,它是如何工作的,如果它也适用于其他人,那么为什么我们使用malloc() 来表示链表而不是简单地分配结构。

【问题讨论】:

  • 您只是觉得这行得通,但事实并非如此。调用更多函数来丢弃堆栈,打印所有值,然后看着它倒下并死掉。
  • @pmr,你是对的。我又叫了几次。实际上,我在第三次拨打prepend 后拨打了printf("%d", list->data)。它打印 30,而不是 10。
  • 我想知道你是如何编译、调试或发布的?通过优化,它可能会更快失败。 @pmr 我认为您在解释和描述 UB =) 方面树立了新的品质。
  • 作为一般规则,您不能使用测试来确定 C 语言中的工作方式:如果它不起作用,则说明您做错了。如果它似乎有效,那么您很可能仍然做错了。

标签: c struct linked-list


【解决方案1】:

在函数prepend中,返回值newNode是一个指向局部变量a的指针。当函数结束时,访问它是未定义的行为。它只是碰巧用这个简单的代码在你的机器上工作,你不能依赖它。

【讨论】:

  • 是的,它不起作用。我刚测试过。如果我在第三次或第四次调用prepend 函数之后调用printf("%d", list->data),它只会打印最后一次调用值。
【解决方案2】:

它不起作用。如果它显示正确的值,那么这纯属巧合,并且内存没有被其他人或其他人覆盖。当prepend() 函数退出时,分配给a 结构的内存被释放。该结构的内存仅在本地上下文中可用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-03
    • 1970-01-01
    • 2010-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多