#c #malloc #valgrind #free
#c #malloc #valgrind #Бесплатно
Вопрос:
Не уверен, где именно 16 байт не освобождаются. Любые мысли о том, где находится последний бесплатный, были бы замечательными. Я также очень новичок в C и программировании в целом.
==23862== HEAP SUMMARY:
==23862== in use at exit: 16 bytes in 1 blocks
==23862== total heap usage: 25 allocs, 24 frees, 2,146 bytes allocated
==23862==
==23862== 16 bytes in 1 blocks are definitely lost in loss record 1 of 1
==23862== at 0x4A069EE: malloc (vg_replace_malloc.c:270)
==23862== by 0x400B5D: read_from_file (sorting.c:145)
==23862== by 0x40093F: main (sorting.c:73)
==23862==
==23862== LEAK SUMMARY:
==23862== definitely lost: 16 bytes in 1 blocks
==23862== indirectly lost: 0 bytes in 0 blocks
==23862== possibly lost: 0 bytes in 0 blocks
==23862== still reachable: 0 bytes in 0 blocks
==23862== suppressed: 0 bytes in 0 blocks
Однако, если я удаляю строку 146, все освобождается, и я получаю четыре ошибки из 4 контекстов, в которых говорится, что условный переход или перемещение зависит от неинициализированных значений.
==31575== Conditional jump or move depends on uninitialised value(s)
==31575== at 0x400E31: length (sorting.c:238)
==31575== by 0x400C7D: bubble_sort (sorting.c:186)
==31575== by 0x4009B8: main (sorting.c:80)
==31575==
==31575== Conditional jump or move depends on uninitialised value(s)
==31575== at 0x400DF3: display (sorting.c:225)
==31575== by 0x4009FC: main (sorting.c:83)
==31575==
==31575== Conditional jump or move depends on uninitialised value(s)
==31575== at 0x4A063A3: free (vg_replace_malloc.c:446)
==31575== by 0x400B2F: destroy (sorting.c:138)
==31575== by 0x400A08: main (sorting.c:85)
==31575==
==31575== Conditional jump or move depends on uninitialised value(s)
==31575== at 0x400B41: destroy (sorting.c:134)
==31575== by 0x400A08: main (sorting.c:85)
Мой код:
typedef struct Data_ {
char *name;
struct Data_ *nextData;
} Data;
int main(int argc, char **argv)
{
Data *head = NULL;
const int size = atoi(argv[2]);
head = read_from_file(argv[1], size); //line 73
head = bubble_sort(head);
destroy(head);
head = NULL;
return 0;
}
Data* read_from_file(const char *file, const int size)
{
Data *head = malloc(sizeof(Data)); //line 145
head = NULL; //line 146
FILE* in;
in = fopen(file,"r");
if(file == NULL)
{
printf("Unable to open %sn",file);
exit(1);
}
char name[MAX_STR_LEN];
int i = 0;
for(;i<size;i )
{
fscanf(in,"%s", name);
push(amp;head,name);
}
fclose(in);
return head;
}
void destroy(Data* list)
{
Data *current = list;
Data *needs_freeing;
while(current)
{
needs_freeing = current;
current = current->nextData;
free(needs_freeing->name);
free(needs_freeing);
}
}
void push(Data **head, char *name)
{
Data *new = malloc(sizeof(Data));
new->name = malloc(sizeof(char)*MAX_STR_LEN);
if(new)
{
strcpy(new->name, name);
new->nextData = *head;
*head = new;
}
}
Data* bubble_sort(Data *list)
{
Data *current;
Data *previous;
char temp[MAX_STR_LEN];
int list_length = length(list);
int i, j;
for(i=1;i<list_length;i )
{
previous = list;
current = previous->nextData;
for(j=0;j<list_length-2;j )
{
if(strcmp(previous->name, current->name) > 0)
{
previous = swap(previous, current);
}
previous = previous->nextData;
current = current->nextData;
}
}
return list;
}
Data* swap(Data *left, Data *right)
{
char temp[MAX_STR_LEN];
strcpy(temp, left->name);
strcpy(left->name, right->name);
strcpy(right->name, temp);
return left;
}
void display(Data *list)
{
FILE* file;
file = fopen("out.txt", "w");
if(file == NULL)
{
printf("Unable to write to filen");
exit(1);
}
while(list->nextData != NULL)
{
fprintf(file,"%sn",list->name);
list = list->nextData;
}
fclose(file);
}
int length(Data* list)
{
int count = 0;
Data* current = list;
while(current)
{
current = current->nextData;
count;
}
return count;
}
Комментарии:
1. Вы не опубликовали некоторые соответствующие части кода, которые вызывают ошибки неинициализированного значения. Кроме того,
name
объявлено в области видимости функции. Это также может быть опасным, еслиpush
ваша собственная функция не аналогична memcpy2. не могли бы вы указать и на другие ошибочные номера строк?
3. существует функция valgrind для поиска источника неинициализированных значений, но я не могу вспомнить, что это такое.
4. Я понял это, или @JonathanLeffler сделал спасибо в любом случае. Это был глупый вопрос.
5. Обратите внимание, что в
push()
у вас есть:Data *new = malloc(sizeof(Data)); new->name = malloc(sizeof(char)*MAX_STR_LEN);
и затем вы проверяете, чтоnew
было выделено. Тест слишком поздний. Вы также должны проверить, чтоnew->name
было успешно выделено. Кроме того, я предлагаю избегать ключевых слов C в C, иnew
это ключевое слово C . (Не все согласятся с «избегать ключевых слов C в C», но я думаю, что это того стоит.)
Ответ №1:
Data *head = malloc(sizeof(Data)); //line 145
head = NULL; //line 146
Это утечка памяти. Вы выделяете память для объекта определенного размера sizeof (Data)
, но затем перезаписываете указатель. Более того, если вы планируете читать или записывать *head
, нет смысла обнулять указатель без использования выделенного объекта.
Комментарии:
1. Да, верно, но затем я удалил эту строку, и все было освобождено, но я получаю четыре ошибки, в которых говорится, что условный переход или перемещение зависит от неинициализированных значений.
2. @user2930353 у вас есть другие проблемы, но вы не поставили полный тестовый пример.
3. @user2930353: Может быть, то, что вы хотели, было
Data *head = calloc(1, sizeof(*head));
или, может бытьhead->name = NULL: head->nextData = NULL;
. Оба они инициализируют выделенную память, что предотвратит другие проблемы, о которых вы упоминаете (или имеют приличные шансы на это).4. да, это работает @JonathanLeffler извините, что сделал тривиальный вопрос таким сложным