2015-01-29 3 views
0

У меня есть указатель на структуру, а один из объектов в структуре - int **. Двойной указатель используется для динамического выделения памяти для 2d-массива. Мне трудно понять, как освободить память для этого массива. Есть идеи?Свободная динамически распределенная память из 2D-массива внутри структуры

struct time_data { 
    int *week; 
    int *sec; 
    int **date; 
}; 
typedef struct time_data time_data; 

time_data *getTime(time_data *timeptr, int rows, int cols) { 
    int i = 0; 
    time_data time; 

    // allocate memory for time.date field 
    time.date = (int **)malloc(rows*(sizeof(int *))); // allocate rows 
    if(time.date == NULL) 
     printf("Out of memory\n"); 
    for(i=0; i<rows; i++) { 
     time.date[i] = (int *)malloc(cols*sizeof(int)); 
     if(time.date[i] == NULL) 
      printf("Out of memory\n"); 
    } 
    timeptr = &time; 
    return timeptr; 
} 

int main(int argc, const char * argv[]) { 
    time_data *time = NULL; 
    int rows = 43200, cols = 6; 
    int i; 
    time = getTime(time, rows, cols); 

    for(i=0; i<rows; i++) 
     free(time->date[i]); // problem here 
    free(time->date); 

} 

Модифицированная версия (в случае, если кто-либо другой подобный вопрос)

struct time_data { 
    int *week; 
    int *sec; 
    int **date; 
}; 
typedef struct time_data time_data; 

time_data *getTime(int rows, int cols) { 
    int i = 0; 
    time_data *time = malloc(sizeof(*time)); 

    // allocate memory for time.date field 
    time->date = (int **)malloc(rows*(sizeof(int *))); // allocate rows 
    if(time->date == NULL) 
     printf("Out of memory\n"); 

    for(i=0; i<rows; i++) { 
     time->date[i] = (int *)malloc(cols*sizeof(int)); 
     if(time->date[i] == NULL) 
      printf("Out of memory\n"); 
    } 
    return time; 
} 

int main(int argc, const char * argv[]) { 
    time_data *time = NULL; 
    int rows = 43200, cols = 6; 
    int i; 
    time = getTime(rows, cols); 

    for(i=0; i<rows; i++) 
     free(time->date[i]); // problem here 
    free(time->date); 
return 0; 
} 
+0

[Не отвергни таНос] (http://stackoverflow.com/questions/605845/ do-i-cast-the-result-of-malloc) – Barmar

+0

Какие идеи? вы делаете это правильно. Просто удалите бросок из malloc. Кроме того, 'printf (« Out of memory \ n »);' недостаточно, вы откладываете прерывание, а не dereferene указатель. –

+1

Вы освобождаете его правильно. Но вы не распределяете его правильно. 'getTime' возвращает адрес локальной переменной, что недопустимо. – Barmar

ответ

2

Ваше освобождение в порядке, но у вас есть серьезная ошибка

timeptr = &time; 
return timeptr; 

вы возвращаете адрес локальная переменная.

Локальная переменная выделяется в кадре стека функции, и как только функция вернется, данные больше не будут существовать.

Вы должны использовать malloc для этого тоже

timeptr = malloc(sizeof(*timeptr)); 

, а также вы должны возвращать int из main()

+0

Я изменил код на malloc память для указателя, но я все еще получаю ту же ошибку, когда пытаюсь освободить память в основном. Тема 1: EXC_BAD_ACCESS (код = 1, адрес 0x0). Если я удаляю цикл for, все работает нормально. Исправьте меня, если я ошибаюсь, полагаю, что я возвращаю адрес в массив 2D, который я выделил. timeptr используется только для хранения этого адреса, пока он не будет возвращен. Нужно ли мне хранить память malloc для всего времени структуры, а не делать это для определенного поля? – biononic

+0

Спасибо, что указал мне в правильном направлении. Я изменил входные аргументы для getTime и избавился от объявления времени time_data и просто использовал указатель на структуру. Пришлось изменить все ссылки на поля в формате time-> date. Кажется, сейчас работает – biononic