c - Valgrind 和分配/释放内存的简单问题

标签 c valgrind

我刚开始使用 Valgrind,在尝试解释结果时遇到问题。我有一个简单的“链表”问题,但 Valgrind 说我的代码有一些问题。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

typedef struct str_list{
    char *str;
    struct str_list *next;
}str_list_t;

str_list_t*
split(char str[], char* sep){
    str_list_t *first = NULL;
    str_list_t *last = NULL;

    char *token = strtok(str, sep);

    while(token != NULL){
        str_list_t *new_node = (str_list_t *)malloc(sizeof(str_list_t));
        new_node->str = token;
        new_node->next = NULL;

        if (first == NULL){
            first = new_node;
            last = new_node;
        }else{
            last->next = new_node;
            last = new_node;

        }
        token = strtok(NULL, sep);

        free(new_node);
    }
    return first;
}


int main(){
    char t[] = "Hello_World";
    str_list_t * test = split(t, "_");
    return 1;

}

Valgrind 输出为:

==9628== Invalid write of size 8
==9628==    at 0x1087BF: split (test.c:26)
==9628==    by 0x108828: main (test.c:40)
==9628==  Address 0x51d7048 is 8 bytes inside a block of size 16 free'd
==9628==    at 0x4C2CDDB: free (vg_replace_malloc.c:530)
==9628==    by 0x1087EB: split (test.c:32)
==9628==    by 0x108828: main (test.c:40)
==9628==  Block was alloc'd at
==9628==    at 0x4C2BBAF: malloc (vg_replace_malloc.c:299)
==9628==    by 0x108782: split (test.c:18)
==9628==    by 0x108828: main (test.c:40)

具体问题出在这一行:

last->next = new_node;
free(new_node);
str_list_t *new_node = (str_list_t *)malloc(sizeof(str_list_t));

最佳答案

我可以通过对代码进行一些更改并添加释放列表节点的函数来解决问题:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

typedef struct str_list{
    char *str;
    struct str_list *next;
}str_list;


str_list_t*
split(char str[] , char* sep){
    str_list_t *first = NULL;
    str_list_t *last = NULL;

    // Returns first token
    char *token = strtok(str, sep);
    while (token != NULL)
    {
        if (first == NULL){
            /*
             * This is first
             * */
            first = (str_list_t *)malloc(sizeof(str_list_t));
            first->str = token;
            first->next = NULL;
            last = first;
        }else{
            /**
             * There are more
             * */
            last->next = (str_list_t *)malloc(sizeof(str_list_t));
            last->next->str = token;
            last->next->next = NULL;
            last = last->next;
        }
        token = strtok(NULL, "_");
    }
    return first;
}
void clean_str_list ( str_list_t *first ){
    /**
     * This function is used to free memory
     *
     *
     * Parameters
     * ----------
     *
     * first -> void pointer to the first element of the str_list.
     *
     * */

    str_list_t *node;

    while((node = first) != NULL){
        first = first->next;
        free(node);
    }
    node = NULL;
}

关于c - Valgrind 和分配/释放内存的简单问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53056371/

相关文章:

c++ - 归并排序程序陷入错误

c - C 中 proc/pid/maps 的堆栈大小

c++ - Valgrind 显示 std::vector<> alloc 的次数超过空闲时间,但没有内存泄漏

valgrind - 在理解 kcachedgrind 输出方面需要帮助

c - Valgrind:大小 1 的读/写无效

c++ - valgrind : invalid read of size 1 during strcpy

c - 插入排序错误

在 C 中将十进制转换为罗马 - 如何从函数返回字符串?

c - 插入双向链表的头部和尾部——仅打印最后插入的尾部项目

c - 为什么 Valgrind 在 realloc() 之后报告无效的 free()?