【问题标题】:valgrind Address 0x421688c is 0 bytes after a block of size 4 alloc'd for linked list having integer datavalgrind 地址 0x421688c 是为具有整数数据的链表分配的大小为 4 的块之后的 0 个字节
【发布时间】:2018-08-21 20:36:28
【问题描述】:

虽然有多个线程相关

valgrind 地址 0x421688c 是在一个大小为 4 的块分配后的 0 个字节

类型的问题,但都是用 strlen 或 '\0' 相关问题表达的,我理解它们。我正在处理整数的链表插入。

void insert_node(lnode **head, int num){
    lnode *temp = NULL;

    temp = calloc(1, sizeof(lnode *));
    if(temp == NULL){
        printf("Memory Allocation failed!\n");
        return;
    }   
    temp->data = num;
    temp->next = NULL;

    if(*head == NULL){
        *head = temp;
    }   
    else{
        temp->next = *head;
        *head = temp;
    }   
}

我做了插入、删除步骤并得到摘要(显示最后几行 valgrind 错误,因为错误在同一个地方):

    > ==3238== 9 errors in context 5 of 5:
    > ==3238== Invalid read of size 4
    > ==3238==    at 0x804873D: display (in /home/skb/santosh_practice/linked_list_progs/single_LL/a.out)
    > ==3238==    by 0x8048636: main (in /home/skb/santosh_practice/linked_list_progs/single_LL/a.out)
    > ==3238==  Address 0x42168fc is 0 bytes after a block of size 4 alloc'd
    > ==3238==    at 0x402C17C: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
    > ==3238==    by 0x8048686: insert_node (in /home/skb/santosh_practice/linked_list_progs/single_LL/a.out)
    > ==3238==    by 0x8048614: main (in /home/skb/santosh_practice/linked_list_progs/single_LL/a.out)
    > ==3238== 
    > ==3238== ERROR
ERROR SUMMARY: 22 errors from 5 contexts (suppressed: 0 from 0)

请告诉我哪里做错了?

【问题讨论】:

  • sizeof(lnode *) -> sizeof(lnode)
  • @MichaelWalz,我试过了,但为什么会这样?内存分配是给指针的!
  • 否;你需要足够的空间来存储结构,并且会得到一个指向那么多空间的指针。
  • 您应该为您的minimal reproducible example 创建一个完整的程序,并使用调试符号对其进行编译,以便 Valgrind 输出包含源代码行号。
  • 我已经这样做了。我只是把 valgrind 总结的最后几行放在这里,因为我知道问题只出在一行。此外,如果我得到了完整的代码和 valgrind,它会填满几页。无论我提供什么,观众都非常清楚。

标签: c linux memory-leaks valgrind


【解决方案1】:

你的问题在于你分配的大小。

lnode *temp = NULL;

temp = calloc(1, sizeof(lnode *));

应该是

lnode *temp = NULL;

temp = calloc(1, sizeof(lnode));

如果您的结构在内存中占用 18 个八位字节,而指针占用 8 个八位字节,则使用第一个代码,您将分配 8 个八位字节而不是 18 个八位字节,这是不够的。

永远不会有错误类型的一个好技巧是这样做

lnode *temp = NULL;

temp = calloc(1, sizeof(*temp));

因为“temp”是“lnode *”的类型,而“*temp”是“lnode”的类型

【讨论】:

  • 这主意不错! temp = calloc(1, sizeof(*temp));,让我感觉内存分配是针对内容的大小,而不是指针的大小。谢谢!
  • 当你给sizeof一个表达式时不需要括号 - 只有当你想要一个type的大小时才需要括号。 temp = calloc(1, sizeof *temp) 更清晰。
【解决方案2】:

您正在为指向lnode指针 分配空间,实际上是您平台上any 指针的大小(在 32 位系统上为 4 个字节,在64 位系统),但您需要为结构 lnode 分配空间,这是指针指向的东西。

  • sizeof(lnode *)指针 的大小(通常在 32 位系统上为 4 个字节,在 64 位系统上为 8 个字节。
  • sizeof(lnode) 是结构体lnode 的大小,取决于结构体的定义方式。

【讨论】:

    猜你喜欢
    • 2023-03-23
    • 2023-03-03
    • 1970-01-01
    • 1970-01-01
    • 2015-03-17
    • 1970-01-01
    • 2012-06-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多