2015-08-26 5 views
0

У меня возникли проблемы с использованием и понимания функции бесплатно() в С.Повторное использование памяти в C

Я пытался писать этот пример, чтобы повторно использовать указатель, но я не понимаю, почему возникает ошибка:

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


typedef struct box 
{ 
    char message[20]; 
}box; 


box *newBox() 
{ 
    box *inBox; 
    inBox = (box *) malloc(sizeof(box)); 

    return inBox; 
} 


int main() 
{ 
    box *temp = NULL; 


    temp = newBox(); 
    strcpy(temp->message, "Hello"); 
    printf("%s\n", temp->message); 

    free(temp); 

    strcpy(temp->message, "World"); 
    printf("%s\n", temp->message); 

    free(temp); 

    strcpy(temp->message, "People"); 
    printf("%s\n", temp->message); 

    return 0; 

} 

выход:

Hello 
World 
memory(531,0x7fff77e9e300) malloc: *** error for object 0x7fe8ba404a90: pointer being freed was not allocated 
*** set a breakpoint in malloc_error_break to debug 
Abort trap: 6 

есть обходной путь, чтобы исправить это?

+2

Правило простое: для каждого указателя вы получили через 'malloc' вам нужно сделать один' free' этого указателя и как только вы сделали 'free' указатель не может быть использована больше. –

+0

после «temp» передается в free(), он доступен для использования в программе. в C, не отбрасывать возвращаемое значение из malloc, так как это void *, поэтому его можно назначить любому другому указателю. Всегда проверяйте (! = NULL) возвращаемое значение из malloc, чтобы убедиться, что операция прошла успешно. – user3629249

ответ

6

Я не знаю, почему у вас есть два free(temp) сек здесь:

temp = newBox(); 
strcpy(temp->message, "Hello"); 
printf("%s\n", temp->message); 

free(temp); /* ? */ 

strcpy(temp->message, "World"); 
printf("%s\n", temp->message); 

free(temp); /* ? */ 

strcpy(temp->message, "People"); 
printf("%s\n", temp->message); 

Этот код должен быть

temp = newBox(); 
strcpy(temp->message, "Hello"); 
printf("%s\n", temp->message); 

strcpy(temp->message, "World"); 
printf("%s\n", temp->message); 

strcpy(temp->message, "People"); 
printf("%s\n", temp->message); 

free(temp); /* Free the allocated memory after use */ 

После того как вы free памяти, Вы не должны использовать его. Итак, free память в конце.


Примечание стороны: Актерский здесь:

inBox = (box *) malloc(sizeof(box)); 

не требуется, и here is why

+0

О, я думал, вам нужно было освободить указатель каждый раз, когда вам нужно указать его на новый объект. – Pyrons

+0

@Cool Guy: +1 за то, что он удаляет бросок. но проблем не должно быть, потому что в комплект поставки включены Destructor

+1

@ ПравиасиМит. Но, как правило, он не согласен с другими причинами, упомянутыми в ссылке. Но это не имеет большого значения, поскольку OP уже включил 'stdlib.h'. Спасибо, что рассказали! –

3
free(temp); 

После того, как вы сделаете это, то память, выделенную malloc() (в данном случае) освобождается.

Таким образом, выделенная память ушла и не может быть использована снова, вам нужно выделить память еще раз, если хотите.

Else free() Память только после выполнения необходимых операций над выделенной памятью.

+1

также он вызывает UB, поскольку одна и та же память освобождается более одного раза. – Destructor

2

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

У вас должен быть ровно один бесплатный на malloc, и вы должны освободить указатель перед его использованием в новом malloc - но это не имеет большого смысла, если вы не выполняете тесты или что не выделяете другой размер памяти (и в что последний случай использования, вы бы лучше использовать realloc)

Предполагая, что у вас есть веские причины для таНос/бесплатные несколько раз (этот код делает не выставлять такое требование), вы могли бы сделать:

int main() 
{ 
    box *temp = NULL; 


    temp = newBox(); 
    strcpy(temp->message, "Hello"); 
    printf("%s\n", temp->message); 

    free(temp); 

    temp = newBox(); 
    strcpy(temp->message, "World"); 
    printf("%s\n", temp->message); 

    free(temp); 

    temp = newBox(); 
    strcpy(temp->message, "People"); 
    printf("%s\n", temp->message); 
    free(temp); 

    return 0; 

} 

И, пожалуйста, не бросайте результат malloc в C! Оно должно быть:

box *newBox() 
{ 
    box *inBox; 
    inBox = malloc(sizeof(box)); 

    return inBox; 
} 
Смежные вопросы