2012-01-14 2 views
2

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

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

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

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

программа не откажет.

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

unsigned char *bla[1000][180]; 

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

Я запускаю Xcode 4.2.1 с целью IOS 5.

+1

В следующий раз, пожалуйста, работайте над форматированием кода, прежде чем отправлять сообщения, спасибо. –

+0

Что произойдет, если вы попытаетесь использовать 'malloc' вместо этого, из любопытства? –

+0

опубликуйте код, который вызывает сбой. – fazo

ответ

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

То есть 640 * 480 * 4 * SizeOf (символ *) байт (приблизительно 4.68mb) памяти в стеке. Я предполагаю, что у вашего приложения нет такого большого количества стека. Возьмите его в кучу - как правило, это не хорошая идея иметь такие огромные вещи в стеке (как локальные переменные).

ли это вместо:

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]) 
+1

Это не 640 * 480 * 4 байта. Это 640 * 480 * 4 указателя, так что это намного больше. (Ошибка также может использоваться в качестве символа 'char * image [640] [480] [4]' как 'char (* image) [640] [480] [4]'. – asaelr

+0

@asaelr Спасибо, исправлено. – Amarghosh

+0

Спасибо Amarghosh. Я пытаюсь создать указатель массива с тремя измерениями [640] [480] [4], который «указывает» на массив байтов (размером 640 * 480 * 4 байта). t хочу выделить любую новую память.Я хочу получить доступ к следующим данным: 'unsigned char red = image [200] [300] [0];' Любая идея, как это сделать? –

7

основной стек потока Иос может hold up to 1MB, но ваш массив 640 * 480 * 4 * sizeof(unsigned char*) байт, что rougly 4.68MB. Следовательно, это распределение не может быть выполнено в основном потоке. Вместо этого вы должны использовать динамическое распределение, которое будет использовать память из кучи.

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

typedef unsigned char image_array[640][480][4]; 
image_array* pointer = ...; // pointer to 640 * 480 * 4 unsigned chars 
+0

+1 за то, что вы указали точный лимит стека и ссылку на его публикацию! – Till

3

Если вы, желая сделать это объявить 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 s.

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

+1

Если изображение должно указывать только на один 3D-массив (а не на массив), вы должны удалить '[640]' – asaelr

+0

Спасибо! Я понял. Очень ценю объяснение. –

+0

@asaelr: Вордс, да, ты прав. Спасибо, что поймал это. – AusCBloke

Смежные вопросы