Почему я получаю EXC_BAD_ACCESS, даже если указатель кажется правильным?

Я начинаю с целочисленного массива test[] который представляет собой набор изображений. Первые два элемента test[] высота и ширина первого изображения. Следующие четыре (height*width) элементы являются значениями пикселей. Следующие шесть представляют следующее изображение и так далее.

Моя цель — получить доступ к изображениям через объекты изображений, не дублируя ничего в test[] массив. Я пытаюсь сделать это через ImageSet::import,

int main(){
int test[] = {2,2,1,2,3,4,
2,2,4,5,6,7,
2,2,9,8,0,9};
ImageSet set = ImageSet();
set.import(test); //ImageSet::import
return 0;
}

ImageSet::import использует переменную курсора для хранения начального индекса следующего изображения.
это вызывает Image::import читать эти данные в объект изображения. Данные для этого конкретного изображения должны начинаться с адреса &data[cursor],

void ImageSet::import(int data[]){
int cursor = 0;
for(int i = 0; i < NUM_SRC_IMAGES; i++){
int height = data[cursor];
int width = data[cursor+1];
source_[i].import(&data[cursor]); //this is Image::import
cursor += height * width + 2;
}
}

В image::import, Я получаю плохой доступ, пытаясь прочитать data[0], По словам отладчика, data[] указывает на правильное значение 2, но EXC_BAD_ACCESS бросается в любом случае, когда я пытаюсь получить это значение через data[0],

void Image::import(int data[]){
height_ = data[0]; //the problem occurs right here
width_ = data[1];
matrix_ = &data[2];
}

Я был бы очень признателен за объяснение того, что я делаю неправильно. Я был бы также признателен за предложения о том, как достичь своей цели без арифметики указателей.

Благодарю вас!

1

Решение

Имея ограниченную информацию в вопросе, я могу предложить следующее:

  1. попробуйте изменить импорт, чтобы быть ImageSet::import(const int* data, size_t size) или … желательно, ImageSet::import(const int (&data[18])) — это позволяет получить четкую ссылку, а не данные [], которые Можно быть оптимизированным при некоторых обстоятельствах. Последний также явно указывает вашим коллегам-разработчикам, что это ссылка на массив (в отличие от указателя). То же самое для Image::import,

  2. В Image::import распечатать значение data (Т.е. &data[0]) — это даст вам знать, если адрес действителен.

  3. в конце цикла в ImageSet::import распечатать значение cursor,

Мое предположение в третьем цикле или около того, значение cursor становится слишком большим, больше 18 лет. Я не знаю, каково ваше намерение … но это cursor += 3 + 4*2 логика (как пример) выглядит очень подозрительно.

0

Другие решения

Я думаю, что на этапе оптимизации компилятор переставляет ваш цикл в

for(int i = 0; i < NUM_SRC_IMAGES; i++){
source_[i].import(&data[cursor]); //this is Image::import
int height = data[cursor];   // -> would also crash, but you don't see it because import crashes earlier
int width = data[cursor+1];
cursor += height * width + 2;
}

И так как вы определили NUM_SRC_IMAGES слишком большим, вы читаете после окончания теста.

Кстати, вы также должны подумать об использовании STL, как стиль итератора, а затем вызвать set.import(begin(test), end(test)); Абстрагируясь от базового типа, вы можете читать данные из любого контейнера. И вы можете проверить до конца, чтобы никогда не читать за конец.

0

По вопросам рекламы [email protected]