我正在进行纹理合成项目。我差不多完成了,但是我的进程在运行时占用了大约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();
}
答案 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
。