Лучший способ работать с массивом указателей в Objective-C? - PullRequest
1 голос
/ 05 января 2009

Я пытаюсь имитировать следующий код Java:

int[][] multi; // DIMENSIONS ARE UNKNOWN AT CREATION TIME
// LATER ON...
multi = new int[10][];
multi[5] = new int[20];
multi[5][11] = 66;
// LATER ON...
multi = null; // PROPER WAY OF FREEING EVERYTHING

Я выпустил следующую версию Objective-C:

int* *multi;
//
multi = malloc(10 * sizeof(int*));
multi[5] = (int *) malloc(20 * sizeof(int));
multi[5][11] = 66;
//
free(multi[5]);
free(multi);

Итак, во-первых, я хотел бы услышать, если это лучший путь. И в основном: я не могу найти способ освободить память каким-то «автоматическим» способом, то есть следующий код вызывает исключения во время выполнения на IPhone:

for (int i = 0; i < 10; i++)
{
    if (multi[i] != NULL) free(multi[i]);
}

Ответы [ 3 ]

7 голосов
/ 05 января 2009

Free не обнуляет адрес памяти в указателе, он просто делает его недействительным. Таким образом, если вы выполняете этот цикл более одного раза, вы получите исключения при попытке освободить память, которая уже была признана недействительной. Вы можете использовать NSPointerArray или обернуть ваши целые числа в объектах и ​​использовать NSMutableArray для своих целей, но если вы просто хотите использовать то, что у вас есть, и вы запускаете цикл более одного раза, вам придется сделать что-то вроде: 1001 *

int **multi;
multi = calloc(10, sizeof(int*));
multi[5] = calloc(20, sizeof(int));
//
multi[5][11] = 66;
//
for( int i = 0; i < 10; i++ ) {
  if( multi[i] ) {
    free(multi[i]);
    multi[i] = NULL;
  }
}
//
free(multi);

Таким образом, если цикл запускается более одного раза, вы не ошибетесь. Кроме того, я использую calloc вместо malloc, потому что он установит все указатели в NULL и целые в 0. Первый параметр - это размер массива, который вы хотите (в вашем случае), а второй параметр - размер типа (так что умножение не требуется).

3 голосов
/ 05 января 2009

Во-первых, предлагаемое решение в вопросе не относится к Objective-C, это стандарт C. Перевод Java-кода на C выглядит корректно.

Во-вторых, предлагаемое «автоматическое» освобождение не может работать: malloc () не инициализирует выделенную память. Я бы вместо этого использовал calloc () или добавил memset () после malloc ().

В-третьих, для версии Objective C я бы рассмотрел объект NSMutableArray, заполненный объектами NSMutableArray, которые сами заполнены объектами NSNumber. Для вашей цели, я думаю, что версия C в порядке.

0 голосов
/ 05 января 2009

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

Кроме того, если вы откладываете инициализацию multi до тех пор, пока не узнаете размеры, вы можете просто инициализировать его, как если бы это был статический массив, а не переменной размера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...