程序耗尽我的所有记忆

时间:2011-12-08 03:13:20

标签: c++ memory-management

我正在进行纹理合成项目。我差不多完成了,但是我的进程在运行时占用了大约2GB的内存。我以为我释放了所有的calloc'ed阵列,但我可能错了。 C ++不是我的专长。

我知道三重指针在C ++中是错误的方式,但我现在对它们更加满意。如果您需要查看更多代码,请告诉我们。谢谢。

MetaPic声明

class MetaPic
{
    public:
        Pic* source;
        Pixel1*** meta;
        int x;
        int y;
        int z;
        MetaPic();
        MetaPic(Pic*);
        MetaPic(const MetaPic&);
        MetaPic(int, int, int);
        MetaPic& operator=(const MetaPic&);
        ~MetaPic();
        void allocateMetaPic();
        void copyPixelData();
        void copyToOutput(Pic*&);
        void copyToMetaOutput(MetaPic&, int, int);
        void copyToSample(MetaPic&, int, int);
        void freeMetaPic();

};

分配三重指针

    void MetaPic::allocateMetaPic()
{
    meta = (Pixel1***)calloc(x, sizeof(Pixel1**));

    for(int i = 0; i < x; i++)
    {
        meta[i] = (Pixel1**)calloc(y, sizeof(Pixel1*));
        for(int j = 0; j < y; j++)
        {
            meta[i][j] = (Pixel1*)calloc(z, sizeof(Pixel1));
        }
    }
}

取消分配三重指针

void MetaPic::freeMetaPic()
{
    for(int j = 0; j < y; j++)
    {
        for(int i = 0; i < z; i++)
            free(meta[i][j]);
    }
    for(int i = 0; i < x; i++)
        free(meta[i]);

    free(meta);
}

析构

MetaPic::~MetaPic()
{
    freeMetaPic();
}

=运营​​商

MetaPic& MetaPic::operator=(const MetaPic& mp)
{
    freeMetaPic();

    source = mp.source;
    x = mp.x;
    y = mp.y;
    z = mp.z;
    allocateMetaPic();
    copyPixelData();

    return *this;
}

复制构造函数

MetaPic::MetaPic(const MetaPic& mp)
{
    source = mp.source;
    x = mp.x;
    y = mp.y;
    z = mp.z;
    allocateMetaPic();
    copyPixelData();
}

2 个答案:

答案 0 :(得分:5)

释放时,您似乎在循环中使用了错误的终止值。只需使freeMetaPic函数撤消分配函数的功能,即:

void MetaPic::freeMetaPic()
{
    for (int i = 0; i < x; i++)
    {
        for (int j = 0; j < y; j++)
        {
            free(meta[i][j]);
        }

        free(meta[i])
    }

    free(meta);
}

答案 1 :(得分:3)

使用free()时释放的内存并不总是在free()时返回给操作系统 - 它可能只能在同一进程中分配 。要确认这一点,请在内存泄漏检查程序(如valgrind)下运行程序,并在程序退出时查看是否报告任何泄漏。此外,作为Eric points out,您似乎使用了错误的终止条件进行释放循环。

如果您希望增加将内存返回到操作系统的可能性,请尝试使用单个malloc或calloc调用分配整个数组,并将其自行划分为所有子数组 - 大型单个分配通常会获得特殊处理(作为副作用)使它们易于返回操作系统。你也可以展平你的数组 - 也就是说,分配一个大的mx * my * mz - 元素数组,并访问元素,例如z + mz * (y + my * x)(这也会比使用多个指针级别快得多)。

我建议只使用一个库来执行这种连续的多维数组分配和查找,例如boost multidimensional array library。这种方式远不那么容易出错,而且比执行多级指针查找要快得多。

供参考,以下是使用boost多维数组的方式:

class MetaPic {
  // ...
  typedef boost::multi_array<Pixel1, 3> array_type;
  typedef array_type::index index;

  array_type image;
};

void MetaPic::allocateMetaPic() {
  image.resize(boost::extents[x][y][z]);
}

void MetaPic::freeMetaPic() {
  // this is only needed to try to force the array to be freed early; you can
  // instead simply allow it to be default-destroyed when MetaPic is destroyed
  image.resize(boost::extents[1][1][1]);
}

可以使用普通语法(即image)访问此image[i][j][k]中的元素。请注意,建议对数组索引使用index类型,但如果您知道它们将在范围内,则可以选择使用常规int