【问题标题】:Sometimes I get EXEC_BAD_ACCESS (Access violation) when reversing an array有时我在反转数组时得到 EXC_BAD_ACCESS(访问冲突)
【发布时间】:2011-03-20 17:42:00
【问题描述】:

我正在使用 OpenEXR 库加载图像。

这工作正常,除了图像被旋转 180 度加载。我使用下面显示的循环来反转数组,但有时程序会退出,xcode 会给我一个 EXEC_BAD_ACCESS 错误(我认为这与 msvc 中的访问冲突相同)。它不会每次都发生,只是每 5-10 次发生一次。

理想情况下,我希望将数组反转到位,尽管这每次都会导致错误并且使用 memcpy 会失败但不会导致错误,只是一个空白图像。我想先知道是什么导致了这个问题。

这是我正在使用的代码:(Rgba 是 4 个“Half”s r、g、b 和 a 的结构,在 OpenEXR 中定义)

Rgba* readRgba(const char filename[], int& width, int& height){
    Rgba* pixelBuffer = new Rgba[width * height];
    Rgba* temp = new Rgba[width * height];

    // ....EXR Loading code....

    // TODO: *Sometimes* the following code results in a bad memory access error. No idea why.
    // Flip the image to conform with OpenGL coordinates.
    for (int i = 0; i < height; i++){
        for(int j = 0; j < width; j++){
            temp[(i*width)+j] = pixelBuffer[(width*height)-(i*width)+j];
        }
    }

        delete pixelBuffer;

        return temp;
}

提前致谢!

【问题讨论】:

    标签: c++ arrays access-violation openexr


    【解决方案1】:

    变化:

            temp[(i*width)+j] = pixelBuffer[(width*height)-(i*width)+j];
    

    到:

            temp[(i*width)+j] = pixelBuffer[(width*height)-(i*width)+j - 1];
    

    (提示:想想当 i = 0 和 j = 0 时会发生什么!)

    【讨论】:

    • 哦,是的,我画了一个反转如何工作的图表,花了一段时间仔细弄清楚并忘记了-1!谢谢。不过,我仍然有同样的问题,每运行 5-10 次。
    【解决方案2】:

    您可以通过以下方式优化此代码,以节省内存和循环:

     Rgba* readRgba(const char filename[], int& width, int& height)
     {
        Rgba* pixelBuffer = new Rgba[width * height];
        Rgba tempPixel;
    
        // ....EXR Loading code....
    
        // Flip the image to conform with OpenGL coordinates.
        for (int i = 0; i <= height/2; i++)
          for(int j = 0; j < width && (i*width + j) <= (height*width/2); j++)
          {
            tempPixel =  pixelBuffer[i*width + j];
            pixelBuffer[i*width + j] = pixelBuffer[height*width - (i*width + j) -1];
            pixelBuffer[height*width - (i*width + j) -1] = tempPixel;
          }
    
        return pixelBuffer;
     }
    

    请注意,最佳(从内存使用最佳实践的角度来看)是将 pixelBuffer* 作为参数传递并已分配。在同一段代码中分配和释放内存是一种很好的做法。

    【讨论】:

    • 谢谢,由于各种原因,我尝试反转一半数组失败。该错误现在似乎消失了,但它仍然不能解释为什么它只是有时会发生,所以我想我会把这个问题留得更久一点。我注意到你现在正在做 iheight(而不是 iwidth)。这是因为我以错误的顺序读取图像元素还是出于性能原因?谢谢。
    • 做 iheight 是个错误 :) 抱歉。我会更正代码。在我的测试中,我反转了一个高度等于宽度的矩阵,因此我没有这个问题。但是现在如果你使用带有 iheight 而不是 i*width 的代码,如果 height width 就会出现问题。我将更正代码 sn-p。感谢您指出我的错误:)
    • 我将加载的文件用作 OpenGL 纹理,这(通常)意味着高度 = 宽度,这可能就是代码对我来说很好的原因。很遗憾,我无法回答为什么我有时只会收到错误,但是由于您的代码有效并且具有我最初计划使用的方法,我会接受您的回答。
    • 很抱歉,但我不知道您为什么会出现错误。您最初发布的带有 Paul 更正的代码应该可以工作。它可能与您加载文件的方式有关。作为练习,您可以尝试实现一个简单的程序,该程序生成一个包含随机数的矩阵,然后使用您的原始函数将其反转。
    猜你喜欢
    • 2012-05-15
    • 2013-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-24
    相关资源
    最近更新 更多