C++ 正确释放具有底层连续内存的多维数组

标签 c++ multidimensional-array memory-management new-operator delete-operator

我有一个为 3d 数组分配内存的函数。目标是保证内存是连续的,但也有 a[k][j][i] 语法的便利性:

double *** allocate_3d(const int& sz, const int& sy, const int& sx){
    double * aMem = new double[sz*sy*sx];
    double *** array = new double**[sz];
    for(int k=0; k<sz; k++){
        array[k] = new double*[sy];
        for(int j=0; j<sy; j++){
            array[k][j]= aMem + k*sy*sx + j*sx;
        }
    }
    return array;
}

假设我这样调用函数

x   = allocate_3d(wdz,wdy,wdx);

我怎样才能正确地解除分配 x?我尝试了以下方法:

void delete_3d(double *** array, const int& sz, const int& sy, const int& sx){
    for(int k=0; k<sz; k++){    
        for(int j=0; j<sy; j++){
            delete[] array[k][j];
        }
        delete[] array[k];
    }
    delete[] array;
}

但是运行 Valgrind 会报错,似乎表明内存未正确释放。

最佳答案

其实应该是这样的:

void delete_3d(double *** array, const int& sz, const int& sy, const int& sx) {
    // first, restore the pointer to the actual aMem
    double * aMem = array[0][0];
    // only one dimension was allocated in the loop,
    // so only one loop should be deallocating things
    for(int k = 0; k < sz; k++) {
        delete [] array[k];
    }
    delete[] array;
    delete[] aMem;
}


更好的解决方案

包装 std::vector 以同时获得:连续内存和相当简单的访问语法,并且作为奖励没有额外的数组,这对内存、性能和维护更好:

class Array3d {
public:
    Array3d(size_t sx, size_t sy, size_t sz)
        : m_sx(sx), m_sy(sy) {
        m_array.resize(sx * sy * sz);
    }

    // Can't overload operator[] with more that one parameter
    // so we'll have to do with operator()
    double &operator()(size_t x, size_t y, size_t z) {
        size_t index = x * m_sx * m_sy + y * m_sy + z;
        return m_array[index];
    }

private:
    size_t m_sx, m_sy;
    std::vector<double> m_array;
};

使用示例:

Array3d array(3, 3, 3);
array(0, 1, 2) = 3.14;

关于C++ 正确释放具有底层连续内存的多维数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55443819/

相关文章:

c++ - 等价于 Matlab 的 sum(A)?

c++ - 等待线程如何影响性能?

c++ - C++中的 friend 声明-公共(public)和私有(private)之间的区别

c - 如何分析 C 程序的内存使用情况

python - np.arange与C++iota对比,iota更慢

c++ - 返回对动态生成的二维数组的引用

c++ - 写入多维 vector 的子元素内的元素是线程安全的吗?

c++ - 将矩阵中的 16 位写入文本文件,在 C++ 中以不同的方式读回它们

c++ - C++中的动态分配和大数据结构

c++ - 我必须使用 ->Release() 吗?