0

次の C++ メソッドがあります。

void MyClass::FindBottom ( CIppImage& bwImage, FieldRec* obField, int& bottomBorder_top, int& bottomBorder_bottom, int& topBorder_top, int& topBorder_bottom, bool& algoFoundBorder ){

    int scanYStart = topBorder_top + obField->getH() - VERTICAL_SCAN_AMOUNT;
    int scanYEnd = topBorder_top + obField->getH() + ( VERTICAL_SCAN_AMOUNT * 1.5 );
    int scanAmount = scanYEnd - scanYStart;
    int xScanEnd = obField->getOX() + obField->getW();

    int* histogram = new int[ scanAmount ];
    memset ( histogram, 0, (scanAmount) * sizeof(int) );

    Ipp8u* bwDataPtr = bwImage.DataPtr();

    int bwLineWidth = ( bwImage.Width() + 7 ) / 8;
    int n = 0;

    for( int y = scanYStart; y <= scanYEnd; y++ ){
        for( int x = obField->getOX(); x < xScanEnd; x++ ){
            if( ( GETBYTE( bwDataPtr, x, y, bwLineWidth ) ) != 0 && ( GETPIXEL(bwDataPtr, x, y, bwLineWidth ) ) != 0 ){
                histogram [ n ]++;
            }
        }
        n++;
    }

    int numFillPixelsThreshold = (int)(HORIZ_FILL_THRESHOLD * obField->getW());
    vector<int> goodRows;
    for( int j = 0; j < VERTICAL_SCAN_AMOUNT+VERTICAL_SCAN_AMOUNT+1; j ++ ){
        if( histogram[ j ] >= numFillPixelsThreshold ) {
            goodRows.push_back( scanYStart + j );
        }
    }
    if( goodRows.size() > 0 ){
        bottomBorder_top = goodRows[0];
     bottomBorder_bottom = goodRows[goodRows.size()-1];
    algoFoundBorder = true;
    }else{
        bottomBorder_top    = obField->getOY() + obField->getH() - 4;
        bottomBorder_bottom = obField->getOY() + obField->getH() + 4;
        algoFoundBorder = false;
    }
    delete[] histogram;
    histogram = 0;
}

呼び出しによってプログラムがクラッシュする特定のインスタンスが 1 つありますdelete[]。Visual Studio はエラー メッセージを返します。

ヒープ破損が検出されました: 0x01214980 のノーマル ブロック (#44325) の後、CRT は、ヒープ バッファーの終了後にアプリケーションがメモリに書き込みを行ったことを検出しました。

何か案は?

4

3 に答える 3

1

配列のサイズは ですscanYEnd - scanYStart

[scanYStart, scanYEnd]あなたのループは、そのサイズが配列よりも 1 大きい包括的な範囲をカバーしているため、割り当てられたメモリを超えて書き込みます。配列を 1 要素大きくする必要があります。

(トピック外ですがstd::vector、この関数から例外がスローされたときのメモリリークを修正するために、手動で割り当てられた配列ではなく使用することもお勧めします。push_backサイズを計算する必要がないように、ループ内で使用できます。)

于 2013-03-29T12:32:14.477 に答える
1
int scanAmount = scanYEnd - scanYStart; 
int n = 0; 
for( int y = scanYStart; y <= scanYEnd; y++ ){
   n++;
}
ASSERT(n == scanAmount); // failed, because your for loop makes one more step and as a result you corrupt heap
于 2013-03-29T12:32:14.827 に答える
0

このコードには少なくとも 1 つの問題があります。scanYStartが 0 で、が 10 であるとしましょう。配列scanYEndのサイズhistogramは 10 (10-0) です。そして、ループ内for( int y = scanYStart; y <= scanYEnd; y++ ){で 0 から 10 (10 を含む) まで繰り返します。つまり、11 回繰り返します。行にヒープの破損がありhistogram [ n ]++;、n は 10 です。

于 2013-03-29T12:36:02.087 に答える