内存分配的专用功能会导致内存泄漏吗?

Big*_*iga 1 c++ memory-leaks

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)

Eva*_*ran 7

那里没有内存泄漏,但你应该使用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数组.