1

次のような関数があります。

void foo(){
     Mat mat(50000, 200, CV_32FC1);

     /* some manipulation using mat */

     }

次に、いくつかのループの後(各ループで1回呼び出しますfoo())、エラーが発生します:

OpenCV エラー: メモリ割り当て時 (約 1G) のメモリが不足しています。

私の理解では、Matはローカルであり、foo()返されると自動的に割り当てが解除されるため、なぜリークするのか疑問に思っています。

また、一部のデータでリークしますが、すべてではありません。

これが私の実際のコードです:

bool VidBOW::readFeatPoints(int sidx, int eidx, cv::Mat &keys, cv::Mat &descs, cv::Mat &codes, int &barrier) {
    // initialize buffers for keys and descriptors
    int num = 50000; /// a large number
    int nDims = 0; /// feature dimensions


    if (featName == "STIP")
        nDims = 162;

    Mat descsBuff(num, nDims, CV_32FC1);
    Mat keysBuff(num, 3, CV_32FC1);
    Mat codesBuff(num, 3000, CV_64FC1);

    // move overlapping codes from a previous window to buffer
    int idxPre = -1;
    int numPre = keys.rows;
    int numMov = 0; /// number of overlapping points to move

    for (int i = 0; i < numPre; ++i) {
        if (keys.at<float>(i, 0) >= sidx) {
            idxPre = i;
            break;
        }
    }

    if (idxPre > 0) {
        numMov = numPre - idxPre;
        keys.rowRange(idxPre, numPre).copyTo(keysBuff.rowRange(0, numMov));
        codes.rowRange(idxPre, numPre).copyTo(codesBuff.rowRange(0, numMov));
    }

    // the starting row in code matrix where new codes from the updated features to add in
    barrier = numMov;

    // read keys and descriptors from feature file
    int count = 0; /// number of new points that are read in buffers
    if (featName == "STIP")
        count = readSTIPFeatPoints(numMov, eidx, keysBuff, descsBuff);

    // update keys, descriptors and codes matrix
    descsBuff.rowRange(0, count).copyTo(descs);
    keysBuff.rowRange(0, numMov+count).copyTo(keys);
    codesBuff.rowRange(0, numMov+count).copyTo(codes);

    // see if reaching the end of a feature file
    bool flag = false;

    if (feof(fpfeat))
        flag = true;

    return flag;
}
4

1 に答える 1

1

関数を呼び出すコードを投稿していないため、これが本当のメモリ リークかどうかはわかりません。内部で割り当てたMatオブジェクトはreadFeatPoints()正しく割り当て解除されるため、メモリ リークは見られません。

あなたは宣言しMat codesBuff(num, 3000, CV_64FC1);ます。ではnum = 5000、これは 1 つの大きなブロックに 1.2 ギガバイトのメモリを割り当てようとしていることを意味します。codesまた、次の行を使用して、このデータの一部を にコピーします。

codesBuff.rowRange(0, numMov+count).copyTo(codes);

反復間で の値がnumMove + count変化すると、 のデータ バッファが再割り当てされcodesます。値が十分に大きい場合は、ループの反復間で保持される大量のメモリを消費している可能性もあります。これらは両方とも、ヒープ の断片化につながる可能性があります。待機中の 1.2 GB のメモリ チャンクが存在しない場合、メモリ不足エラーが発生します。これは、経験したことです。

于 2013-07-25T19:41:28.940 に答える