2013-09-11 2 views
3

Я не могу понять, насколько я ошибаюсь.Адрес Valgrind находится в стеке Thread's

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

Ваше понимание струн в 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().

То же самое верно для поля str (с аргументом ts).

+0

спасибо. И ты прав! Начиная работать со строками после ДЛИННОГО перерыва. Полностью забыл про strdup. Еще раз спасибо! – user2266603

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); 
0

Это решается, но я хотел бы уточнить кое-что, так как я получаю много «Invalid записи размера п» ошибки в моих журналах VALGRIND. Я думал, что использую слишком много пространства для стека, но это было совсем не так.

Если вы вызываете fprintf и направляете вывод на stderr, все эти вызовы будут отображаться в Valgrind. И человек, они пополнят ваш журнал. Один вызов fprintf генерирует около 300 из этих ошибок.

например.

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

Пополнит ваши журналы Valgrind. Я беспокоился о том, что что-то было серьезно неправильным, и я не мог найти свою проблему. Как оказалось, проблем не было, и я просто потратил впустую последние 45 минут.

Смежные вопросы