为什么即使指针看起来有效,我也会得到EXC_BAD_ACCESS?

时间:2014-07-02 03:50:11

标签: c++ arrays pointers 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];
}

我非常感谢我解释我做错了什么。我同样赞赏如何在没有指针算术的情况下实现目标的建议。

谢谢!

2 个答案:

答案 0 :(得分: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));通过从底层类型中抽象,您可以从任何容器中读取数据。而且你可以检查结果,所以你永远不会读到结束。

答案 1 :(得分:0)

由于问题中的信息有限,我可以提出以下建议:

  1. 尝试将导入更改为ImageSet::import(const int* data, size_t size)或...最好是ImageSet::import(const int (&data[18])) - 这样可以提供明确的参考,而不是可以的数据[]在某些情况下被优化掉。后者还明确地向你的伙伴devs指出它是一个数组引用(而不是指针)。 Image::import相同。

  2. Image::import中打印出data的值(即&data[0]) - 这会告诉您地址是否有效。

  3. ImageSet::import循环结束时打印出cursor的值。

  4. 我的猜测是在第三个循环左右,cursor的值增长得太大,大于18.我不知道你的意图是什么......但cursor += 3 + 4*2逻辑(作为一个例子)看起来很可疑。