2014-09-16 4 views
0

Начальные:C ошибка двойного освобождения

создание динамического массива структуры данных, называемой дробями. Фракции имеют функции для настройки, печати, подсказки и т. Д.

Я продолжал получать ошибку за двойное освобождение или повреждение, а также много тарабарщины с карты памяти. Это ошибка с выхода:

двойной бесплатно или повреждение (сверху): 0x0000000001976010 *

Я понимаю, что она будет освобождена/удалены два раза, но вот код, который генерирует сообщение об ошибке:

#include <stdio.h> 
#include <stdlib.h> 
#include "fraction.h" 

main() { 
    long long int size = 0; 
    long long int capacity = 10; 
    int FSize = sizeof(struct fraction); 
    struct fraction* array = NULL; 
    struct fraction in; 
    array = (struct fraction*)malloc(FSize * capacity); 
    if (array == NULL) { 
     printf("MALLOC DID NOT WORK\n"); 
     exit(1); 
    } 
    int i = 0; 
    for (i = 0; i < 17; i++) { 
     if (size == capacity) { 
      capacity = capacity * 2; 
      struct fraction* temp = NULL; 
      temp = (struct fraction*)realloc(array, FSize * capacity); 
      // free(array); 
      array = temp; 
      free(temp); 
     } 
     SetFrac(&in); 
     array[size++] = in; 
    } 
    printf("IT MADE IT HERE >>>>>>>>>>>>>>>>>> \n"); 
    getchar(); 
    for (i = 0; i < size; i++) { 
     struct fraction t = array[i]; 
     PrintFrac(&t); 
    } 
    free(array); 
    return 0; 
} 

Вот код, который работает

#include <stdio.h> 
#include <stdlib.h> 
#include "fraction.h" 

main() { 
    long long int size = 0; 
    long long int capacity = 10; 
    int FSize = sizeof(struct fraction); 
    struct fraction* array = NULL; 
    struct fraction in; 
    array = (struct fraction*)malloc(FSize * capacity); 
    if (array == NULL) { 
     printf("MALLOC DID NOT WORK\n"); 
     exit(1); 
    } 
    int i = 0; 
    for (i = 0; i < 17; i++) { 
     if (size == capacity) { 
      capacity = capacity * 2; 
      struct fraction* temp = NULL; 
      temp = (struct fraction*)realloc(array, FSize * capacity); 
      // free(array); 
      array = temp; 
      free(temp); 
     } 
     SetFrac(&in); 
     array[size++] = in; 
    } 
    printf("IT MADE IT HERE >>>>>>>>>>>>>>>>>> \n"); 
    getchar(); 
    for (i = 0; i < size; i++) { 
     struct fraction t = array[i]; 
     PrintFrac(&t); 
    } 
    // free(array); 
    return 0; 
} 

Я использую функцию free() неправильно?

+0

Вы назначаете 'массив = temp', затем освобождая 'temp'. Поскольку 'array' - это одно и то же значение, вы также освободили, по сути,' array'. Но затем вы переходите к использованию 'array' после того, как он был освобожден, что плохо. Почему вы освобождаете его сразу после получения «realloc»? – lurker

ответ

0

Вы должны только освободить «массив» в конце. Вы не должны освобождать «temp», потому что вы продолжите использование блока (array = temp не поддерживает определенный «счетчик ссылок», а просто назначает указатель).

+0

Я просто попытался удалить бесплатно (темп). Он работал без ошибок. Не будет ли утечка памяти, потому что память, расположенная в * temp, не освобождается? – user3339931

+0

Он не должен быть освобожден там и тогда, так как тот же блок по-прежнему ссылается на 'array', и вы все еще используете его через этот указатель. В конце, когда вы больше не обращаетесь к памяти, ее можно безопасно освободить. –

0

После звонка free вы не должны разыгрывать освобожденную память, которую вы делаете, используя array[size++].

Вы не должны free() по темпам там, потому что вы используете array позже.

Ваш последний комментарий free() был бы единственным, который был бы правильным, хотя программа должна работать нормально.

+0

Так что я не свободна от темпа? – user3339931

+1

Действительно, вы не должны освобождать темп. 'array' - это копия указателя, поэтому он указывает на тот же блок памяти, что и' temp' ('array = temp;' не копирует память, а только значение указателя, то есть адрес блока памяти) , Поскольку вы все еще используете блок памяти (через указатель 'array'), он еще не должен быть освобожден. Он должен быть освобожден * после * использования.Другими словами, вы не освобождаете 'temp', вы освобождаете блок памяти, к которому относится' temp' и, позже, 'array'. Вы не должны этого делать, пока вы все еще используете его, т. Е. Не в то время, когда вы делаете это в своем коде. –

1

массив и температура имеют один и тот же адрес указателя, поэтому, когда вы бесплатно темп, массив будет освобожден также

0

Вам не нужно освобождать (темп) после того, как перераспределить темп, только чтобы освободить (массив) конец основного. Если вы перераспределить успех, возможны два варианта:

  1. Темп == массива (температура точки на одной и той же памяти)
  2. массив является свободным и точка температуры в новой памяти
Смежные вопросы