c/c++:如何在C/C++中动态分配二维数组(转)
http://bbs.csdn.net/topics/390337580
如何在C/C++中动态分配二维数组
在C/C++中动态分配二维数组可以先申请一维的指针数组,然后该数组中的每个指针再申请数组,这样就相当于二维数组了,但是这种方法会导致每行可能不相邻,从而访问效率比较低。如何申请连续的二维数组了?本文将分别三个方面讲解:
一.动态申请列大小固定的二维数组
二.C语言中动态申请连续的二维数组
三.C++语言中动态申请连续的二维数组
一.动态申请列大小固定的二维数组
首先如果二维数组的列大小固定,那么很简单,可以用申请一维数数组再其指针强制转化成为二维数组指针即可。详见代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
//列大小固定的二维数组可以申请一维数据并将指针强转成二维数组 //By MoreWindows-(http://blog.csdn.net/MoreWindows) #include <stdio.h> int main() { printf ( " 列大小固定的二维数组可以申请一维数据并将指针强转成二维数组\n" ); printf ( " -- by MoreWindows( http://blog.csdn.net/MoreWindows ) --\n\n" ); //列值固定 const int MAXCOL = 3; int nRow; printf ( "请输入二维数组的行数(列值固定为%d): " , MAXCOL); scanf ( "%d" , &nRow); //申请一维数据并将其转成二维数组指针 int *pp_arr = new int [nRow * MAXCOL]; int (*p)[MAXCOL] = ( int (*)[MAXCOL])pp_arr; //为二维数组赋值 int i, j; for (i = 0; i < nRow; i++) for (j = 0; j < MAXCOL; j++) p[i][j] = i + j; //输出二维数组 for (i = 0; i < nRow; i++) { for (j = 0; j < MAXCOL; j++) printf ( "%5d" , p[i][j]); putchar ( '\n' ); } //释放资源 delete [] pp_arr; return 0; } |
运行结果如下所示:
二.C语言中动态申请连续的二维数组
上面的方法虽然方便,但必须要求列的大小固定。下面先来试下在C语言中如何动态申请连续的二维数组。可以采用多申请一些指针,然后这一些指针分别指向后面数据区中对应的位置,如一个3*4的int类型数组,我们先申请大小为sizeof(int*) * 3 + 3 * 4 * sizeof(int)的一维数组设为arr。然后arr[0]存放指向arr + sizeof(int*) * 3这个位置的指针,arr[1]存放指向arr + sizeof(int*) * 3 + 4 * sizeof(int)这个位置的指针, arr[2]存放指向arr + sizeof(int*) * 3 + 2 * 4 * sizeof(int)这个位置的指针。下面用图展示指向的示意:
详细代码如下,由于指针操作有点小复杂,请读者耐心看:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
//C语言中动态的申请二维数组 malloc free //By MoreWindows-(http://blog.csdn.net/MoreWindows) #include <stdio.h> #include <stdlib.h> #include <string.h> //动态申请二维数组 template < typename T> T** malloc_Array2D( int row, int col) { int size = sizeof (T); int point_size = sizeof (T*); //先申请内存,其中point_size * row表示存放row个行指针 T **arr = (T **) malloc (point_size * row + size * row * col); if (arr != NULL) { memset (arr, 0, point_size * row + size * row * col); T *head = (T*)(( int )arr + point_size * row); while (row--) arr[row] = (T*)(( int )head + row * col * size); } return (T**)arr; } //释放二维数组 void free_Aarray2D( void **arr) { if (arr != NULL) free (arr); } int main() { printf ( " C语言中动态的申请二维数组 malloc free\n" ); printf ( " -- by MoreWindows( http://blog.csdn.net/MoreWindows ) --\n\n" ); printf ( "请输入行列(以空格分开): " ); int nRow, nCol; scanf ( "%d %d" , &nRow, &nCol); //动态申请连续的二维数组 int **p = malloc_Array2D< int >(nRow, nCol); //为二维数组赋值 int i, j; for (i = 0; i < nRow; i++) for (j = 0; j < nCol; j++) p[i][j] = i + j; //输出二维数组 for (i = 0; i < nRow; i++) { for (j = 0; j < nCol; j++) printf ( "%4d " , p[i][j]); putchar ( '\n' ); } free_Aarray2D(( void **)p); return 0; } |
运行结果如下:
三.C++语言中动态申请连续的二维数组
可以看出我们已经成功实现了在C语言中动态申请连续的二维数组,如果上面的程序不使用int类型而使用string类这种类型,那会有什么后果了?肯定的说,由于没有调用构造函数和析构函数,程序绝对会造成内存泄露。因此要做下改进,下面给出在C++语言中动态申请连续的二维数组的代码,有些C++语法可能平时见得少,但其实这些语法在STL里面运用还是比较多的,有兴趣的童鞋应该掌握下。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
//C++语言中动态的申请二维数组 new delete //By MoreWindows-(http://blog.csdn.net/MoreWindows) #include <new> #include <cstdio> #include <cstdlib> #include <string> using namespace std; //动态申请二维数组 template < typename T> T** new_Array2D( int row, int col) { int size = sizeof (T); int point_size = sizeof (T*); //先申请内存,其中sizeof(T*) * row表示存放row个行指针 T **arr = (T **) malloc (point_size * row + size * row * col); if (arr != NULL) { T *head = (T*)(( int )arr + point_size * row); for ( int i = 0; i < row; ++i) { arr[i] = (T*)(( int )head + i * col * size); for ( int j = 0; j < col; ++j) new (&arr[i][j]) T; } } return (T**)arr; } //释放二维数组 template < typename T> void delete_Array2D(T **arr, int row, int col) { for ( int i = 0; i < row; ++i) for ( int j = 0; j < col; ++j) arr[i][j].~T(); if (arr != NULL) free (( void **)arr); } int main() { printf ( " C++语言中动态的申请二维数组 new delete\n" ); printf ( " -- by MoreWindows( http://blog.csdn.net/MoreWindows ) --\n\n" ); printf ( "请输入行列(以空格分开): " ); int nRow, nCol; scanf ( "%d %d" , &nRow, &nCol); //动态申请连续的二维数组 string **p = new_Array2D<string>(nRow, nCol); //为二维数组赋值 int i, j; for (i = 0; i < nRow; i++) for (j = 0; j < nCol; j++) { char szTemp[30]; sprintf (szTemp, "(第%d行,第%d列)" , i, j); p[i][j] = szTemp; } //输出二维数组 for (i = 0; i < nRow; i++) { for (j = 0; j < nCol; j++) printf ( "%s " , p[i][j].c_str()); putchar ( '\n' ); } delete_Array2D<string>(p, nRow, nCol); return 0; } |
运行结果如下:
本贴对应博客文章
http://blog.csdn.net/morewindows/article/details/7664479
更多C/C++/C#基础知识文章请访问:
http://blog.csdn.net/morewindows/article/category/868661
更多Windows编程文章请访问:
http://blog.csdn.net/MoreWindows
欢迎大家讨论交流,回贴必给分。