C++ 删除二维数组C++;

C++ 删除二维数组C++;,c++,arrays,pointers,C++,Arrays,Pointers,释放二维阵列的这两种方法相似吗 int** M = new int*[5]; for (int i = 0; i < 5; ++i) M[i] = new int[3]; for (int i = 0; i < 5; ++i) { for (int j = 0; j < 3; ++j) { M[i][j] = i + j; } } 这两个代码是否等效?delete[]*M与delete[]M[0]相同,因此它并不等同于删除循环中的所

释放二维阵列的这两种方法相似吗

int** M = new int*[5];

for (int i = 0; i < 5; ++i)
    M[i] = new int[3];

for (int i = 0; i < 5; ++i) {
    for (int j = 0; j < 3; ++j) {
        M[i][j] = i + j;
    }
}

这两个代码是否等效?

delete[]*M
delete[]M[0]
相同,因此它并不等同于删除循环中的所有
M[i]
,因为只有第一个将被删除。循环是避免内存泄漏的正确方法


或者更好地使用
std::vector
而不是手动分配,这样您就不必担心删除指针。

它们不相似。它们不相似的明显原因是您调用了6次
new[]
,而在
delete[]
的第二个版本中,您调用了2次“delete”

对于每次调用
new[]
,您都应该将其与
delete[]
匹配,显然您没有这样做

如果希望这两个对
delete[]
的调用相匹配,则必须更改分配2d数组的方式。变化如下:

int** M = new int*[5];
int *pool = new int[5*3];

for (int i = 0; i < 5; ++i, pool += 3)
    M[i] = pool;
int**M=newint*[5];
int*pool=新int[5*3];
对于(int i=0;i<5;++i,池+=3)
M[i]=池;
在上面的示例中,只对
new[]
进行了两次调用,一次调用行指针,另一次调用内存池。然后循环只将池中的每个行指针指向正确的位置

现在,“2调用”
delete[]
将正常工作,前提是您在分配和解除分配阵列期间不会执行任何奇怪的操作,例如内存损坏

以这种方式分配二维数组的优点是,无论列数多少,
new[]
只调用两次。因此,如果您有一个10000 x 10000矩阵,您的原始版本将需要调用
new[]
10001次,而上面使用池的版本只需要调用两次
new[]
。这很可能会加快程序的速度,因为分配器只被调用两次(然后再被释放两次)

此外,如果数组数据需要连续,则首选上述方法,以便可以使用简单的指针算法转到任何行或列

但是,请确保:

  • 您的阵列不会更改大小和大小
  • 它不是参差不齐的(所有行必须具有相同的列数)

否则,维护按照我描述的方式分配的矩阵将变得更加困难。

发生了什么?为什么你什么都不做广告?为什么不使用
std::vectors
?节省了很多钱hassle@EdHeal最好的方法是使用智能指针。但我对使用指针和数组很感兴趣now@user3601739-不是智能指针-尝试
vector(int)>
@EdHeal:It's
vector
。(是的,虽然在可能的情况下通常应该使用
vector
s,但有时应该使用指针,特别是在学习练习时)。
delete [] *M;
delete [] M;
delete [] *M;
delete [] M;
int** M = new int*[5];
int *pool = new int[5*3];

for (int i = 0; i < 5; ++i, pool += 3)
    M[i] = pool;