2014-09-10 3 views
0

У меня есть функция в C, который добавляет новый вопрос к главе односвязного списка:Как освободить память, выделенную указателю в C?

int AddQuestion() 
{ 
    unsigned int aCount = 0; 
    Question* tempQuestion = malloc(sizeof(Question)); 

    tempQuestion->text = malloc(500); 

    fflush(stdin); 
    printf("Add a new question.\n"); 
    printf("Please enter the question text below:\n"); 
    fgets(tempQuestion->text, 500, stdin); 
    printf("\n"); 
    fflush(stdin); 
    printf("How many answers are there?: "); 
    scanf("%u", &tempQuestion->numAnswers); 
    fflush(stdin); 
    tempQuestion->answers = malloc(sizeof(Answer*) * tempQuestion->numAnswers); 
    for (aCount = 0; aCount < tempQuestion->numAnswers; aCount++) 
    { 
     tempQuestion->answers[aCount] = malloc(sizeof(Answer)); 
     tempQuestion->answers[aCount]->content = malloc(250); 
     printf("Enter answer #%d: \n", (aCount + 1)); 
     fgets(tempQuestion->answers[aCount]->content, 250, stdin); 
     fflush(stdin); 
     printf("Is it correct or wrong? correct = 1, wrong = 0: "); 
     scanf("%u", &tempQuestion->answers[aCount]->status); 
     fflush(stdin); 
    } 

    tempQuestion->pNext = exam.phead; 
    exam.phead = tempQuestion; 

    printf("\n"); 
    fflush(stdin); 

    return 1; 
} 

Как вы можете видеть, я использую таНос(), чтобы выделить пространство, что нужно для нового вопроса , Однако, если я попытаюсь вызвать free() на tempQuestion, он удалит вопрос с экзамена. Я не хочу удалять вопрос, если вопрос не будет удален или программа не завершится.

У меня есть функция очистки, которая должна освобождать() всю используемую память, но она не освобождает tempQuestion в функции addQuestion().

void CleanUp() 
{ 
    unsigned int i = 0; 
    Question* tempQuestion = NULL; 

    if (exam.phead != NULL) { 
     while (exam.phead->pNext != NULL) { 
      tempQuestion = exam.phead; 
      exam.phead = tempQuestion->pNext; 
      for (i = 0; i < tempQuestion->numAnswers; i++) { 
       free(tempQuestion->answers[i]->content); 
       free(tempQuestion->answers[i]); 
      } 
      free(tempQuestion->pNext); 
      free(tempQuestion->text); 
      free(tempQuestion); 
     } 
     free(exam.phead); 
    } 
} 

Как бы я освобождаю() tempQuestion в моей функции addQuestion(), так что он освобождает только память, когда исполнение заканчивается? Я использую Visual Studio C++ 2012, но мне приходится писать только синтаксис C (нет C++). Я довольно новичок в программировании на C. Благодаря!

+2

Обратите внимание, что технически 'fflush (stdin)' не определено, это допускается некоторыми реализациями как расширение, но это явно неопределенное поведение в спецификации C. –

+1

Кроме того, в C [вы не должны бросать возврат 'malloc'] (http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc). –

+0

С синтаксисом «Си» вы технически не хотите бросать 'malloc', но вы * должны * при компиляции C++. – crashmstr

ответ

1

Чтобы ответить на ваш вопрос: вы этого не сделаете. Вы не должны звонить free(tempQuestion) в функцию AddQuestion, потому что это освобождает только что выделенную память.

Когда вы назначаете указатель на другой указатель, это только указатель , который копируется, а не то, на что он указывает.

+0

Вот что я подумал, но я был не уверен. Есть ли способ, чтобы я мог освободить память, когда выполнение заканчивается (т. Е. Внутри CleanUp())? –

+0

@BenjaminC.Huskisson-Snider: Зачем вообще освобождать память, когда программа выходит? Ваша платформа не освобождает все ресурсы программ? – Deduplicator

+0

@ BenjaminC.Huskisson-Snider Мне кажется, что вы уже это делаете. Но вы также вызываете 'free' на указателях, которых вы не должны, например' tempQuestion-> pNext' (это вызывает [* неопределенное поведение *] (http://en.wikipedia.org/wiki/Undefined_behavior) на следующей итерации цикла, когда вы разыгрываете теперь нераспределенный указатель). С другой стороны, вы забудете освободить 'tempQuestion-> answer'. –

0

Выделить и освободить память для tempQuestion в главном вместо выделения в функциях AddQuestion.

int main() 
{ 
    Question *tempQuestion = malloc (sizeof (Question)); 
    . 
    . 
    . 
    free (tempQuestion); 
    return 0; 
} 

Это поможет вам освободить память для tempQuestion только перед возвращением из основных.

Также во время освобождения памяти для tempQuestion-> ответ вы пропустили этот

for (i = 0; i < tempQuestion->numAnswers; i++) { 
    free(tempQuestion->answers[i]->content); 
    free(tempQuestion->answers[i]); 
} 
free (tempQuestion->answer); 

Rest должно быть в порядке.

+0

Пожалуйста, прочтите: https://stackoverflow.com/questions/25766121/how-would-i-free-memory-allocated-to-a-pointer-in-c#comment40292911_25766121 – Deduplicator

+0

Извините @Deduplicator Я не понимаю вашу точку зрения , – Adarsh

+0

Приведение возвращаемого значения 'malloc' в лучшем случае плохого стиля и ненужный источник ошибок. И передача типа 'sizeof' вместо разыменованного целевого указателя немного более подвержена ошибкам, чем необходимо. Прочитайте [Q & A для литья возвращаемого значения 'malloc'] (http://stackoverflow.com/q/605845) – Deduplicator

0

В конце AddQuestion()tempQuestion указывает на тот же адрес, что exam.phead указывает, таким образом CleanUp() освобождает эту память для вас.

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