#c #arrays #pointers #exc-bad-access
#c #массивы #указатели #исключение-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
чтение этих данных в объект изображения. Данные для этого конкретного изображения должны начинаться с адреса amp;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(amp;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_ = amp;data[2];
}
Я был бы очень признателен за объяснение того, что я делаю неправильно. Я также был бы признателен за предложения о том, как достичь моей цели без арифметики указателей.
Спасибо!
Комментарии:
1. Вы пробовали передавать его как
source_[i].import(data cursor)
?2. Пожалуйста, полную программу. sscce.org
3. Добавьте пару операторов печати после
for(int i = 0; i < NUM_SRC_IMAGES; i ){
для печатиi
иcursor
, чтобы убедиться, что вы не пытаетесь получить доступ к памяти сверх того, что вы должны.4. Проблема с чтением данных [0] или проблема с записью height_?
5. Почему вы не используете const? Почему вы не используете итераторы? Вы уверены, что я
Ответ №1:
Учитывая ограниченную информацию в вопросе, я могу предложить следующее:
-
попробуйте изменить import на
ImageSet::import(const int* data, size_t size)
или … предпочтительно,ImageSet::import(const int (amp;data[18]))
— это позволяет получить четкую ссылку в отличие от data[], которые могут быть оптимизированы при некоторых обстоятельствах. Последний также явно указывает вашим коллегам-разработчикам, что это ссылка на массив (в отличие от указателя). То же самое дляImage::import
. -
В
Image::import
распечатайте значениеdata
(т. Е.amp;data[0]
) — это позволит вам узнать, действителен ли адрес. -
в конце цикла в
ImageSet::import
распечатайте значениеcursor
.
Я предполагаю, что в третьем цикле или около того значение cursor
становится слишком большим, больше 18. Я не знаю, каковы ваши намерения… но эта cursor = 3 4*2
логика (в качестве примера) выглядит действительно подозрительной.
Ответ №2:
Я предполагаю, что на этапе оптимизации компилятор перестраивает ваш цикл на
for(int i = 0; i < NUM_SRC_IMAGES; i ){
source_[i].import(amp;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));
Абстрагируясь от базового типа, вы могли бы читать данные из любого контейнера. И вы можете свериться с концом, чтобы никогда не читать дальше конца.