Hy all,
我相信下面这段代码会产生内存泄漏?
/* External function to dynamically allocate a vector */
template <class T>
T *dvector(int n){
T *v;
v = (T *)malloc(n*sizeof(T));
return v;
}
/* Function that calls DVECTOR and, after computation, frees it */
void DiscontinuousGalerkin_Domain::computeFaceInviscidFluxes(){
int e,f,n,p;
double *Left_Conserved;
Left_Conserved = dvector<double>(NumberOfProperties);
//do stuff with Left_Conserved
//
free(Left_Conserved);
return;
}
Run Code Online (Sandbox Code Playgroud)
我认为,通过将指针传递给DVECTOR,它将分配它并返回正确的地址,以便free(Left_Conserved)成功解除分配.但是,似乎并非如此.
注意:我也测试过new/delete替换malloc/free也没有成功.
我有一个用于分配二维数组的类似代码.我决定管理这样的矢量/数组,因为我经常使用它们,而且我也想了解使用C++进行更深入的内存管理.
所以,我非常希望保留一个外部函数来为我分配向量和数组.这里有什么能避免内存泄漏的问题?
编辑
我一直在使用DVECTOR函数来分配用户定义的类型,所以这可能是一个问题,我想,因为我没有调用构造函数.
即使在我释放Left_Conserved向量之前的代码段中,我也想分配一个向量并将其保持为"open"以通过其指针通过其他函数进行评估.如果使用BOOST,它会在函数结束时自动清除分配,所以,我不会得到一个带有BOOST的"公共"数组,对吗?我想用NEW很容易解决这个问题,但对于矩阵来说,更好的方法是什么?
我刚刚发现我将指针作为参数传递给其他函数.现在,BOOST似乎没有那么多享受它,并且编译以错误退出.
因此,我需要一个指向矢量或矩阵的指针,它接受用户定义的类型,它们将作为参数传递给其他函数.矢量(或矩阵)很可能在外部函数中分配,并在另一个合适的函数中释放.(我只是不想复制循环和新的东西,在代码中的任何地方分配矩阵!)
这是我想做的事情:
template <class T>
T **dmatrix(int m, int n){
T **A;
A = (T **)malloc(m*sizeof(T *));
A[0] = (T *)malloc(m*n*sizeof(T));
for(int i=1;i<m;i++){
A[i] = A[i-1]+n;
}
return A;
}
void Element::setElement(int Ptot, int Qtot){
double **MassMatrix;
MassMatrix = dmatrix<myT>(Ptot,Qtot);
FillInTheMatrix(MassMatrix);
return;
}
Run Code Online (Sandbox Code Playgroud)
那里没有内存泄漏,但你应该使用new/delete []而不是malloc/free.特别是因为你的功能是模板化的.
如果您想要使用具有非平凡构造函数的类型,则基于malloc的函数会被破坏,因为它不会调用任何构造函数.
我只需要这样做就可以取代"dvector":
void DiscontinuousGalerkin_Domain::computeFaceInviscidFluxes(){
double *Left_Conserved = new double[NumberOfProperties];
//do stuff with Left_Conserved
//
delete[] Left_Conserved;
}
Run Code Online (Sandbox Code Playgroud)
它在功能上是等效的(除了它可以为其他类型调用构造函数).它更简单,需要更少的代码.此外,每个c ++程序员都会立即知道发生了什么,因为它不涉及额外的功能.
更好的是,使用智能指针完全避免内存泄漏:
void DiscontinuousGalerkin_Domain::computeFaceInviscidFluxes(){
boost::scoped_array<double> Left_Conserved(new double[NumberOfProperties]);
//do stuff with Left_Conserved
//
}
Run Code Online (Sandbox Code Playgroud)
许多聪明的程序员都喜欢说"最好的代码就是代码,你不必写"
编辑:为什么你认为你发布的代码泄漏内存?
编辑:我看到你对另一篇文章的评论说
在代码执行命令顶部显示分配的内存无限增长!
这可能完全正常(或可能不是),具体取决于您的分配模式.通常,堆的工作方式是它们经常增长,但不会经常缩小(这有利于后续分配).完全对称的分配和释放应该允许应用程序稳定在一定的使用量.
例如:
while(1) {
free(malloc(100));
}
Run Code Online (Sandbox Code Playgroud)
不应该导致持续增长,因为堆很可能为每个malloc提供相同的块.
所以我的问题是.它是"无限期地"增长还是仅仅没有缩小?
编辑:
您已经询问如何处理2D阵列.就个人而言,我会用一个类来包装细节.我要么使用一个库(我相信boost有一个n-dimmentional数组类),或者你自己滚动应该不会太难.这样的事情可能就足够了:
http://www.codef00.com/code/matrix.h
用法是这样的:
Matrix<int> m(2, 3);
m[1][2] = 10;
Run Code Online (Sandbox Code Playgroud)
使用像operator()这样的东西来索引矩阵包装类在技术上更有效,但在这种情况下我选择模拟本机数组语法.如果效率非常重要,那么它可以像本机阵列一样高效.
编辑:另一个问题.你在开发什么平台?如果它是*nix,那么我会建议valgrind来帮助查明你的内存泄漏.由于您提供的代码显然不是问题.
我不知道,但我相信Windows也有内存分析工具.
编辑:对于矩阵,如果你坚持使用普通的旧数组,为什么不把它作为一个连续的块分配,并做索引的简单数学,如下所示:
T *const p = new T[width * height];
Run Code Online (Sandbox Code Playgroud)
然后访问一个元素,只需这样做:
p[y * width + x] = whatever;
Run Code Online (Sandbox Code Playgroud)
这样你就可以delete[]在指针上做一个1D或2D数组.