Я начинаю с целочисленного массива 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];
}
Я был бы очень признателен за объяснение того, что я делаю неправильно. Я был бы также признателен за предложения о том, как достичь своей цели без арифметики указателей.
Благодарю вас!
Имея ограниченную информацию в вопросе, я могу предложить следующее:
попробуйте изменить импорт, чтобы быть ImageSet::import(const int* data, size_t size)
или … желательно, ImageSet::import(const int (&data[18]))
— это позволяет получить четкую ссылку, а не данные [], которые Можно быть оптимизированным при некоторых обстоятельствах. Последний также явно указывает вашим коллегам-разработчикам, что это ссылка на массив (в отличие от указателя). То же самое для Image::import
,
В Image::import
распечатать значение data
(Т.е. &data[0]
) — это даст вам знать, если адрес действителен.
в конце цикла в ImageSet::import
распечатать значение cursor
,
Мое предположение в третьем цикле или около того, значение cursor
становится слишком большим, больше 18 лет. Я не знаю, каково ваше намерение … но это cursor += 3 + 4*2
логика (как пример) выглядит очень подозрительно.
Я думаю, что на этапе оптимизации компилятор переставляет ваш цикл в
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));
Абстрагируясь от базового типа, вы можете читать данные из любого контейнера. И вы можете проверить до конца, чтобы никогда не читать за конец.