2016-10-12 2 views
3

Если у меня есть 2D массив, выделенный следующим образом:C освободив 2D массив, если таНос сбой

int** map; 
map = malloc(number * sizeof(int*)); 
if(!(map)){ 
    printf("out of memory!\n"); 
    return 1; 
} 
for (int i = 0; i < number; i++){ 
    map[i] = malloc(number * sizeof(int)); 
    if (!(map[i])){ 
     printf("Not enough memory!\n"); 
     return 1; 
    } 
} 

Если распределение не удается, и мы вступаем в, если заявлении не я должен Бесплатная карта и «колонна» выделены до сих пор ? Если да, то как мне это сделать?

Прямо сейчас я просто распечатаю сообщение и вернусь 1, но я не уверен, что это правильный подход.

+0

У вас нет 2D-массива. Это справочная таблица с указателем. Чтобы выделить 2D-массив, вы должны использовать 'int (* map) [number] = malloc (sizeof (int [число] [число])) или эквивалент. Разница в том, что 2D-массив имеет свои данные, выделенные в соседних ячейках памяти, очень важно понять. – Lundin

+0

Не забудьте проверить возвращаемое значение внешнего malloc. – user464502

+0

@ Lundin О, я не знал, что, кроме того, что данные распределены по-разному, есть ли другие отличия в том, как их использовать/скорость? –

ответ

2

Вы можете использовать:

if (!(map[i])){ 
    printf("Not enough memory!\n"); 

    while (--i>=0) 
     free(map[i]); 

    free(map); 
    return 1; 
} 
6

Да, вы должны free() иначе утечки памяти, которые могли бы значения, если это находится в длительной программе.

Один из способов облегчить вычисление общего размера всех распределений и сделать один крупный malloc(), а не целую кучу меньших. Это также (потенциально много) быстрее, так как распределение кучи может быть дорогостоящим.

Таким образом, вам нужно только один раз проверить, удалось ли это или не удалось, и нет ничего, чтобы free() в случае отказа.

Что-то вроде этого:

int ** map_allocate(size_t number) 
{ 
    int **base = malloc(number * sizeof (int *) + number * number * sizeof (int)); 
    if(base != NULL) 
    { 
    int *row = (int *) (base + number); 
    for(size_t i = 0; i < number; ++i) 
     base[i] = row + i * number; 
    } 
    return base; 
} 

Я не тест-запустить, но что-то вдоль этих линий.

+0

mh, это еще быстрее для действительно больших карт, к которым обращаются много, или это потенциально медленнее в долгосрочной перспективе, так как я должен рассчитать, где мой номер каждый раз? Если это почти всегда быстрее, я мог бы использовать решение, подобное вашему (мне нужно сэкономить столько времени, сколько смогу от выполнения моей программы) –

+0

@JohnSmith Что? Я не предлагал никакой другой структуры данных, ничего, чтобы «рассчитать, где мой номер», что бы это ни значило, все, что я предложил, было альтернативным способом * выделения * массива массивов. Я смущен. – unwind

+0

Да, я плохо, я неправильно понял, что вы писали –

0

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

int **map; 

map = malloc(number * sizeof(int *)); 
if(!map) 
    goto out_of_memory; 
for(i=0;i<number;i++) 
    map[i] = 0; 

for(i=0;i<numbers;i++) 
{ 
    map[i] = malloc(number * sizeof(int)); 
    if(!map[i]) 
     goto out_of_memory; 
} 

... 

return 0; 

out_of_memory: 
    if(map) 
     for(i=0;i<number;i++) 
      free(map[i]); 
    free(map); 
    return -1; 
Смежные вопросы