Valgrind地址位于Thread的1堆栈上

时间:2013-09-11 16:40:22

标签: c valgrind

我无法弄清楚我的生活中我做错了什么。

T* tokenizer = create(argv[1], argv[2]);
destroy(tokenizer);

这是结构:

struct T_
{
    char *sep_set;
    char *str;
    char *token;
    int *last_index;
};
typedef struct T_ T;

这是创建功能:

T *create(char *separators, char *ts)
{
    T *tk = malloc(sizeof(struct T_));
    tk->sep_set = malloc(sizeof(char)*strlen(separators));
    tk->str = malloc(sizeof(char)*strlen(ts));
    tk->last_index = malloc(sizeof(int));
    tk->sep_set = separators;
    tk->str = ts;
    *tk->last_index = 0;
    return tk;
}

void destroy(T *tk)
{
    free(tk->sep_set);
    free(tk->str);
    free(tk->last_index);
    free(tk);
}

我的错误是:

==12302== Invalid free() / delete / delete[] / realloc()
==12302==    at 0x4C273F0: free (vg_replace_malloc.c:446)
==12302==    by 0x400649: destroy (t.c:58)
==12302==    by 0x40088C: main (t.c:145)
==12302==  Address 0x7ff0006e7 is on thread 1's stack
==12302== 
==12302== Invalid free() / delete / delete[] / realloc()
==12302==    at 0x4C273F0: free (vg_replace_malloc.c:446)
==12302==    by 0x400659: destroy (t.c:59)
==12302==    by 0x40088C: main (t.c:145)
==12302==  Address 0x7ff0006ec is on thread 1's stack

第58和59行是

free(tk->sep_set);
free(tk->str);

非常感谢任何帮助!

3 个答案:

答案 0 :(得分:3)

你对C语言的掌握似乎让你失望。

此:

tk->sep_set = malloc(sizeof(char)*strlen(separators));
tk->sep_set = separators;

错误,它用malloc()参数指针覆盖separators返回的指针,将句柄丢弃到泄漏的内存中。然后将错误的指针传递给free(),这是无效的。

应该是:

tk->sep_set = strdup(separators);

如果你有,否则:

if((tk->sep_set = malloc(strlen(separators) + 1)) != NULL)
    strcpy(tk->sep_set, separators);

有些观点:

  1. 您必须在长度上加1才能为'\0'终结符腾出空间。
  2. 您不需要sizeof (char)“缩放”,保证为1,所以它只是杂乱无章。
  3. 您必须检查malloc()是否失败。
  4. 您必须使用strcpy()复制字符串。
  5. str字段(ts参数)也是如此。

答案 1 :(得分:2)

尝试替换

tk->sep_set = malloc(sizeof(char)*strlen(separators));
tk->str = malloc(sizeof(char)*strlen(ts));
tk->sep_set = separators;
tk->str = ts;

tk->sep_set = strdup(separators);
tk->str = strdup(ts);

答案 2 :(得分:0)

这已经解决了,但我想澄清一些事情,因为我得到了很多"无效的写入大小n"我的Valgrind日志中的错误。我以为我使用了太多的堆栈空间,但事实并非如此。

如果您调用fprintf并将输出定向到stderr,则所有这些调用都将显示在Valgrind中。而且,他们会填满你的日志。一次fprintf调用产生了大约300个错误。

e.g。

    fprintf(stderr,"I want to print %d and %d", num1, num2);

将填写您的Valgrind日志。我担心出现严重错误,我无法找到问题所在。事实证明,没有任何问题,我只是在过去的45分钟内浪费了。