Valgrind和分配/可用内存的简单问题

时间:2018-10-30 02:03:00

标签: 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));

1 个答案:

答案 0 :(得分:1)

我可以解决在代码中进行一些更改并添加释放列表节点的功能的问题:

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