前几天去科大讯飞面试,其他问题回答的都还不错,但是被问到这个“如何动态申请一个连续内存空间的二维数组”时,稍微顿了一下。倒不是回答不上来,而是之前从没有尝试敲过这样的代码,光说思路实在是太干瘪。
回来以后,尝试了几段代码,又和不少人讨论了一下,把代码撸了出来。
先说思路:对于要求的x*y的二维数组,可以先申请一段连续的x*y内存空间,然后通过指向指针的指针的重新定位每行开头的位置。
刚开始和本人讨论的时候,不少人给了这样的代码:
int **p2 = new int *[x];
for (int i = 0; i < x; i++)
p2[i] = new int[y];
但是,这段代码只是用来动态申请二维数组的,循环x次来申请长度为y的内存空间时,只能保证每一行的空间是连续的,并不能保证第n行的最后一个元素和第n+1行第一个元素的地址是连续的。
后来尝试了一下,给出了正确的代码:
int **p1 = new int *[x];
*p1 = new int[x*y];
for (int i = 0; i < y; i++)
p1[i] = *p1 + i*y;
一次性申请了x*y的空间,然后通过循环,重新定位每行第一个元素的所指向的地址。保证了二维数组从头到尾的连续性。
两段代码整合比对;
#include <iostream>
#include <cstdlib>
using namespace std;
int main(int argc,char *argv[])
{
int x, y;
cin >> x >> y;
cout << "动态连续二维数组" << endl;
int **p1 = new int *[x];
*p1 = new int[x*y];
for (int i = 0; i < y; i++)
p1[i] = *p1 + i*y;
for (int i = 0; i < x; i++)
for (int j = 0; j < y; j++)
p1[i][j] = i + j;
for (int i = 0; i < x; i++)
{
for (int j = 0; j < y; j++)
cout << &p1[i][j] << " ";
cout << endl;
}
cout << "动态离散二维数组" << endl;
int **p2 = new int *[x];
for (int i = 0; i < x; i++)
p2[i] = new int[y];
for (int i = 0; i < x; i++)
{
for (int j = 0; j < y; j++)
cout << &p2[i][j] << " ";
cout << endl;
}
system("pause");
return 0;
}
专门将两种申请二维数组方式的最后二维数组的地址给输出出来
很明显,第二种方式确实不是连续空间的二维数组。