Указатель массива в с / объективе с - PullRequest
2 голосов
/ 15 января 2012

У меня проблемы с указателями массива в c / target c. Когда я выполняю свой код, я получаю сообщение об ошибке BAD ACCESS. Я прибил заявление, которое вылетает из приложения:

unsigned char *image[640][480][4];

Если я изменю заявление на:

unsigned char *image[640][10][4];

программа не падает.

Это утверждение также приводит к сбою приложения:

unsigned char *bla[1000][180];

Есть идеи, почему размер массива вызывает сбой? Это просто объявление указателя массива.

Я использую Xcode 4.2.1 с целью IOS 5.

Ответы [ 3 ]

6 голосов
/ 15 января 2012

стек основных потоков iOS может содержать до 1 МБ , но размер вашего массива составляет 640 * 480 * 4 * sizeof(unsigned char*) байт, что составляет примерно 4,68 МБ. Следовательно, это распределение не может быть успешным в главном потоке. Вместо этого вы должны использовать динамическое распределение, которое будет использовать память из кучи.

Если вы действительно имели в виду, что image - это указатель на трехмерный массив, я рекомендую вам использовать typedef, чтобы его было легче читать:

typedef unsigned char image_array[640][480][4];
image_array* pointer = ...; // pointer to 640 * 480 * 4 unsigned chars
4 голосов
/ 15 января 2012
char *image[640][480][4];

Это 640 * 480 * 4 * размер (char *) байтов (приблизительно 4,68 МБ) памяти в стеке. Я предполагаю, что у вашего приложения не так много стека. Возьмите его в кучу - обычно не очень хорошая идея иметь в стеке такие огромные вещи (как локальные переменные).

Сделайте это вместо:

char *image;

image = malloc(640 * 480 * 4 * sizeof(char*));

if(!image){
  printf("oops - even malloc failed\n");
  exit(1);
}

Обратите внимание, что вы больше не можете обращаться к изображению в виде трехмерного массива. Такие выражения, как image[i][j][k], следует заменить на image[i * 480 * 4 + j * 4 + k]

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

#define GET_IMAGE_POINTER_AT(image, i, j, k)  (image[(i) * 480 * 4 + (j) * 4 + k])
3 голосов
/ 15 января 2012

Если вы хотите объявить image как указатель на массив , а не как массив указателей , то вы должны объявить его так::

unsigned char (*image)[480][4];

Вы не указываете первое измерение массива, потому что именно на этот указатель указывает первый элемент в массиве.* по существу заменяет [640].

Тогда, например, если у вас есть массив unsigned char test[640][480][4] (при условии, что это не произойдет сбой), ваш код будет просто:

unsigned char test[640][480][4];
unsigned char (*image)[480][4] = test;

Ваш код объявляет многомерный массив char* с, тогда как этот код объявляет указатель на многомерный массив char с.

Причина, по которойизменение 480 на 10 может остановить сбой кода, потому что вы, скорее всего, пытаетесь использовать больше места, чем то, что доступно в стеке, путем создания фактического массива такого большого размера, а не указателя наодин.

...