请考虑以下代码:
#include <Windows.h>
#include <stdio.h>
void print2d(int** A,int Y,int X)
{
for(int i=0;i<Y;i++)
{
for(int j=0;j<X;j++)
printf("%d ", A[i][j]);
printf("\n");
}
}
int main()
{
int Y=2;
int X=4;
int** tab2d=new int*[Y];
for(int i=0;i<Y;i++)
{
tab2d[i]=new int[X];
for(int j=0;j<X;j++)
tab2d[i][j]=0;
}
int* row=new int[X];
for(int i=0;i<X;i++)
row[i]=i;
int option=0;
switch(option)
{
case 0:
tab2d[Y-1]=row;
case 1:
for(int i=0;i<X;i++)
tab2d[Y-1][i]=i;
}
print2d(tab2d,Y,X);
free(tab2d);
free(row);
system("pause");
}
鉴于在实际代码中,2d数组会有很多迭代,对于case 0或case 1有什么优势吗?分配新的行指针似乎是一种更好的方法,但它不会在整个内存中分隔我的数组行吗?
答案 0 :(得分:1)
这两种解决方案并不相同。
案例0: 此处,数组元素将更改为指向您已创建的新行(即初始化行时分配的行)。这几乎肯定不是你因为a)它留下内存泄漏,因为你最初创建的数组元素永远不会被释放,另外当你删除行时,tab2d指向的内存不再有效(一旦访问它将导致未定义的行为 - 最有可能是崩溃)。
案例1: 你期望它做什么。
另外我想你需要知道,一般来说你的最终删除不会删除指针在2D数组中引用的对象,只是删除数组本身。因此,即使在案例1中,您也会产生非常严重的内存泄漏。
答案 1 :(得分:1)
一些事情:
1)如果你的行都是相同数量的列,那么创建和销毁2d数组的一般方法是次优的。请参阅此处另一种方法的答案:
2)至于创建一个新行只是为了替换值 - 为什么要创建一个全新的行?为什么不必要地调用allocator(和deallocator来删除旧行)?为什么不直接更改2d数组的现有行中的值?
我可以看到你是否在运行时删除或向你的2d数组添加行,然后你就可以在创建行和销毁各行时合理。但是,如果你不改变二维数组的大小,只需更改二维数组中的值,就不要创建新行。
答案 2 :(得分:-1)
首先,不要一起使用new / delete和malloc / free。否则行为未定义。 其次,您的第3个声明不得缩进。 关于你的问题: 对于代码中的每个new / malloc,应该存在匹配的delete / free。 在选项0(甚至选项1)中,您将丢失对tab2d [Y-1]的引用,导致内存泄漏,并在删除'row'和'tab2d [Y-1]时结束时双删除虽然它们都指向相同的地址,但行为未定义。
在这里,你在选项0中所做的是不正确的,但是如果你做了你想要正确做的事情,并且根据情况,它可以更有效的方式。