-3

ここで発生しているメモリリークを見つけるのを手伝ってもらえますか? 設計した Image クラスを使用して、1600x960 24 ビット RAW イメージ (46,08,000 バイト) をメモリにロードしようとしています。タスクマネージャーで見ると、メモリでは30MBかかります..

デストラクタが呼び出された (範囲外になった) 後でも、まだ 2M を占めています。助けてください!

#include <cstdio>
#include <iostream>

struct pixel {
    char* color;  // to support various BPP
};

class Image
{
    private:
        pixel** image;
        int     width;
        int     height;
        int     BPP;    // bytes per pixel
        int     size;   // in bytes

    public:
        Image(std::string src, int width, int height, int BPP);
        ~Image();
        pixel** get_matrix(int col, int row, int BPP);
};

pixel** Image :: get_matrix(int col, int row, int BPP)
{
            pixel** matrix = new pixel*[row];
            for(int i=0 ; i<row ; i++)
            {
                matrix[i] = new pixel[col];
                for(int j=0 ; j<col ; j++)
                    matrix[i][j].color = new char[BPP];
            }
            return matrix;
}

Image :: Image(std::string src, int width, int height, int BPP)
{
    FILE *in;
    if( (in = fopen(src.c_str(), "rb")) == NULL )
        image = NULL;
    else
    {
        this->height = height;
        this->width  = width;
        this->BPP    = BPP;
        this->size   = width*BPP*height;

        image = get_matrix(width,height,BPP);
        char* buffer = new char[size];
        fread(buffer, sizeof(char), size, in);

        int l=0;
        for(int i=0 ; i<height ; i++)
        {
            for(int j=0 ; j<width ; j++)
            {
                for(int k=0 ; k<BPP ; k++)
                    image[i][j].color[k] = buffer[l++];
            }
        }
        delete []buffer;
        fclose(in);
    }
}

Image :: ~Image()
{
    for(int i=0 ; i<height ; i++)
    {
        for(int j=0 ; j<width ; j++)
            delete []image[i][j].color;
        delete []image[i];
    }
    delete []image;
}

int main()
{
    {
        getchar();
        Image in("x.raw", 1600, 960, 3);
        getchar();
    }
    getchar();
}
4

1 に答える 1

2

そこでメモリリークを見つけることはできませんが、プログラムはメモリの面でかなり無駄です。

  1. ロード時に、ファイル全体をメモリにロードしてから、マトリックスを作成します。ロードの最後に、ファイルとマトリックスの両方がメモリにあります。フォーマットが許せば、ファイルを繰り返し(たとえば、行ごとに)ロードしようとする可能性があります。

  2. 画像行列の保存形式は、配列の配列の配列です。各次元の配列は個別に割り当てられ、割り当てられた配列ごとに、メモリアロケータの内部に使用されるメモリ(通常は8〜16バイト)がいくらかあるため、マトリックスを格納するこのような方法は大量のメモリを浪費します。プレーンを使用してみてくださいstd::vector<>。たとえば、理想的には次のようになります。

    struct RGB24 { uint8_t r, g, b; }; // one for each pixel format
    std::vector<RGB24> image(width * height); // allocate the matrix in one shot
    RGB24& pixel = image[row * width + col]; // get pixel image[row][col] 
    
于 2013-01-21T17:45:52.743 に答える