C++ C++;正确解除多维数组与底层连续内存的分配

C++ C++;正确解除多维数组与底层连续内存的分配,c++,multidimensional-array,memory-management,new-operator,delete-operator,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++){

我有一个为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?我尝试了以下方法:

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;
}
void delete_3d(双***数组,常量int&sz,常量int&sy,常量int&sx){

对于(int k=0;k),实际上应该是这样的:

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;
}
用法示例:

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

实际上应该是这样的:

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;
}
用法示例:

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


避免整个头痛,使用
std::vector
为您分配并正确释放所有内存。上面写的任何内容都不需要显式
new
delete
。向量可以为您做任何事情。这就是向量的用途。我可能错了,但我认为我无法获得语法
A[k][I]
,如果我使用矢量矢量的矢量,则具有连续内存。@EternusVia
数组[0][0]
为您提供
aMem
。避免整个头痛问题,使用
std::vector
为您分配并正确释放所有内存。上面写的任何内容都不需要显式
new
delete
。向量可以为您做任何事情。这就是向量的用途。我可能错了,但我认为我无法得到答案ntax
a[k][j][i]
并且如果我使用向量向量的向量,则具有连续内存。上面的每个动态分配对象都可以替换为等效向量。
aMem
array
都可以是向量。结束。向量保证连续内存。@EternusVia
array[0][0]给你<代码> AIMM 。谢谢你回答我的问题。@ EntutuVas,也请考虑我已经添加的另一个解决方案。谢谢你的额外输入。我可以问一下,在性能上如何更好地使用类方法?相同的转换单元,因此不会有任何开销。另一方面,数组的层次结构在每个级别上增加了额外的间接寻址,CPU“不喜欢”间接寻址,因为它不利于缓存性能,而且您必须为每个元素访问多个单独的数组,这也不利于缓存,因为它们可能“无处不在”在内存中。@EternusVia,在您实际对代码进行基准测试之前,所有这些性能考虑都是纯理论性的。您应该始终首先测量性能,然后在必要时进行优化,否则您将只是痴迷于此,无缘无故地使代码更加复杂。谢谢您回答我的问题Uclipse。@ EntUnVIAS,也请考虑我已经添加的另一个解决方案。谢谢您的额外输入。我可以问一下,在性能上如何更好地使用类方法?@ EutnUnVIAS,如果在同一个翻译单元中定义,类方法几乎肯定会被编译器内联,因此不会有开销。另一方面,数组的层次结构在每个级别上都添加了额外的间接寻址,CPU“不喜欢”间接寻址,因为这对缓存性能不利,而且您必须为每个元素访问多个单独的数组,这对缓存也不利,因为它们可能“无处不在”在内存中。@EternusVia,无论如何,在您实际对代码进行基准测试之前,所有这些性能考虑都是纯理论的。您应该始终首先测量性能,然后在必要时进行优化,否则您只会痴迷于此,毫无理由地使代码更加复杂。