如何在C/C++中动态分配二维数组
上一篇 /
下一篇 2012-06-20 09:48:10
/ 个人分类:C++
在C/C++中动态分配二维数组可以先申请一维的指针数组,然后该数组中的每个指针再申请数组,这样就相当于二维数组了,但是这种方法会导致每行可能不相邻,从而访问效率比较低。如何申请连续的二维数组了?本文将分别三个方面讲解:51Testing软件测试网7x2u-OLi6F 一、动态申请列大小固定的二维数组
i,h3^/s1L6c"Ny0 二、C语言中动态申请连续的二维数组51Testing软件测试网I8Gn'`3f*V+R-n
三、C++语言中动态申请连续的二维数组51Testing软件测试网
Lt9r6\r
OuSL#Ea0 一、动态申请列大小固定的二维数组51Testing软件测试网QaA#`F#NiX&VN
51Testing软件测试网}I@0i|5x+VD^'v 首先如果二维数组的列大小固定,那么很简单,可以用申请一维数数组再其指针强制转化成为二维数组指针即可。详见代码:51Testing软件测试网*s9?'Tv @?%f
51Testing软件测试网 d:t,])o/{2^*E //列大小固定的二维数组可以申请一维数据并将指针强转成二维数组51Testing软件测试网@d2t8x1XC3_ #include <stdio.h> "TP{
rIn"T0int main() J/t{3pBz^5PE7Az0{51Testing软件测试网NR~l$Jo.m{)v printf(" 列大小固定的二维数组可以申请一维数据并将指针强转成二维数组\n"); 51Testing软件测试网
a gC(I+m[[a printf(" -- by MoreWindows( http://blog.csdn.net/MoreWindows ) --\n\n"); \:wxI^!i051Testing软件测试网Sf8K^N"XA\4vT v //列值固定51Testing软件测试网'D+h O:b$G s const int MAXCOL = 3;51Testing软件测试网:I4Gct4FG'p 51Testing软件测试网};S'^{2cDnV(HSw int nRow; w u1^tQR1o2\e"N0 printf("请输入二维数组的行数(列值固定为%d): ", MAXCOL);51Testing软件测试网u_u2D:[ scanf("%d", &nRow);51Testing软件测试网l1u8y3Q-iK#IR0S*ls +a1{TH(f0 //申请一维数据并将其转成二维数组指针51Testing软件测试网.]!^0i^3RS:U5tw_ int *pp_arr = new int[nRow * MAXCOL];51Testing软件测试网B [5OPN#n/] L0Q int (*p)[MAXCOL] = (int(*)[MAXCOL])pp_arr;51Testing软件测试网wd'Un/e-gC4e +?*e'q@z#]/X)V0 //为二维数组赋值 [1{:S
de"DP+H2c"`0 int i, j; q ^&VN:I0 for (i = 0; i < nRow; i++)51Testing软件测试网7[\7q~1p|^ for (j = 0; j < MAXCOL; j++) S8n7b9j%g0 p[i][j] = i + j;51Testing软件测试网6o7Q^5V5b2v#Y0s-I/_8K 51Testing软件测试网)OT*JB
p8{4`r //输出二维数组51Testing软件测试网4]3i*RdbA\y q)T;{ for (i = 0; i < nRow; i++)
xEo.GkQ3w%c0 { l+J2T-R0g7f6C
m0 for (j = 0; j < MAXCOL; j++)51Testing软件测试网$BCxumP
h o;Ng printf("%5d", p[i][j]);51Testing软件测试网%d}mG4tM6^ putchar('\n'); 8|!x]
SM$L&w0 } 2gvA
x3KS$S051Testing软件测试网u$i k F+^8Ey //释放资源 s;dbU0cm*@)js2\A0 delete[] pp_arr; BH1V pj~0 return 0; uz:q)e]v5Zq{0}51Testing软件测试网3rc.p{i-s
Xs/u |
TjMT,T(DTc%f0 运行结果如下所示:
*c5IA]&q%j0
C%ESzM#I5T0K9AA0二、C语言中动态申请连续的二维数组
R)x![-z9["b9l*g$W0
T.}9@;OB3N0 上面的方法虽然方便,但必须要求列的大小固定。下面先来试下在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)这个位置的指针。下面用图展示指向的示意:51Testing软件测试网oX
H!O T?/k;F?/MD
51Testing软件测试网 @TboeO
详细代码如下,由于指针操作有点小复杂,请读者耐心看:
[wB3Yl s6}qK08j5xTs:G051Testing软件测试网2EI2tdc8o-a*^'E //C语言中动态的申请二维数组 malloc free iy2gRYm0#include <stdio.h>51Testing软件测试网3J AUc.R
p*V9R #include <stdlib.h>51Testing软件测试网5s|p0FG n
u #include <string.h> )gA.K!n'M0XF
C0//动态申请二维数组 v9L};ld0template <typename T> oda6f^r!T_0T** malloc_Array2D(int row, int col)51Testing软件测试网 ^
a&r
B3A
p6] A { (z/x8P+X3jK:j-O0 int size = sizeof(T); ;W9z|ye\0 int point_size = sizeof(T*);51Testing软件测试网!J ^
Q"X.YC/\R //先申请内存,其中point_size * row表示存放row个行指针 6Q6l:\K|4Vi?i2D ]3C0 T **arr = (T **) malloc(point_size * row + size * row * col);51Testing软件测试网4um)\sB7}D if (arr != NULL) 9w8W8uM B0m0 { /\`
q"f2T@ Qx#Q0 memset(arr, 0, point_size * row + size * row * col); R }6~3a!d]X0 T *head = (T*)((int)arr + point_size * row);51Testing软件测试网iBLQ)s}U!s while (row--)51Testing软件测试网r#RsGDMi2I arr[row] = (T*)((int)head + row * col * size); *W`m9XQ0 }51Testing软件测试网!Fv&woyI2k
C@$n return (T**)arr;51Testing软件测试网-mc4_\SF } -u?,G7VFQO0//释放二维数组51Testing软件测试网K9u1G?_ Bu void free_Aarray2D(void **arr)51Testing软件测试网\$nh/N'L#F\HU2\7i { )i9b`DT0p0 if (arr != NULL) 4C/Wh5G9fbO&J,P9F Z0 free(arr); "v!}(c'y
u\J0} _?i7X1s&i,o0int main()51Testing软件测试网5kj'{[9[2}
M
e A { 1pa2@a X;M7BY?3`$X0 printf(" C语言中动态的申请二维数组 malloc free\n"); 51Testing软件测试网4F+}Ryg-YA5Z printf(" -- by MoreWindows( http://blog.csdn.net/MoreWindows ) --\n\n"); 4Pd8dN5_8t9N051Testing软件测试网:wZW B)p7\[NF printf("请输入行列(以空格分开): ");51Testing软件测试网1XjnN7Q2u~ int nRow, nCol;51Testing软件测试网7P+kE)x&Vn+Z scanf("%d %d", &nRow, &nCol);51Testing软件测试网)Pf+f:J\ 2v#Vu4|wF&O0 //动态申请连续的二维数组51Testing软件测试网Bf5aY9xNV:FT int **p = malloc_Array2D<int>(nRow, nCol);51Testing软件测试网L+\)~9hR zU 51Testing软件测试网%s.k1a{&TN //为二维数组赋值 WxL6TIFi0 int i, j; S pP#v&xUQ0 for (i = 0; i < nRow; i++)51Testing软件测试网R0|p k0F for (j = 0; j < nCol; j++) nb,vI
kA0 p[i][j] = i + j; %w8WPs_051Testing软件测试网r%F Q X8l3c6C4z //输出二维数组 51Testing软件测试网]`"s!r!P u{.~Fz&r for (i = 0; i < nRow; i++)
J%sTa Y#Pd.Ou0 { 6^1C&~
[EJ5q#v@3L0\h0 for (j = 0; j < nCol; j++)51Testing软件测试网K Gh,}0?
s'E1D printf("%4d ", p[i][j]); Kc*k&Kl {:D:G0 putchar('\n');51Testing软件测试网d:` d`
d4b;M9Z }51Testing软件测试网`V}]\G4L 51Testing软件测试网1sLx cJ0T:p free_Aarray2D((void**)p); 1\;a/NO9pe`g&L1X0 return 0;51Testing软件测试网8v^Nk,jF;Y:l hR.ert } 4ROG'uBt0 |
运行结果如下:
d
U*wV4K5M+DL!t0
/DYz(ZBrI6EX'{0三、C++语言中动态申请连续的二维数组
1g1_:]6Z0w6S#FR9Ag0.A'OJ$g
s*K8i!l0 可以看出我们已经成功实现了在C语言中动态申请连续的二维数组,如果上面的程序不使用int类型而使用string类这种类型,那会有什么后果
了?肯定的说,由于没有调用构造函数和析构函数,程序绝对会造成内存泄露。因此要做下改进,下面给出在C++语言中动态申请连续的二维数组的代码,有些
C++语法可能平时见得少,但其实这些语法在STL里面运用还是比较多的,有兴趣的童鞋应该掌握下。51Testing软件测试网7b4\$z1m^#yF,s
51Testing软件测试网L6h FNgB51Testing软件测试网P'z|Z;S]
1v$s0_[*z#pdh0//C++语言中动态的申请二维数组 new delete51Testing软件测试网 gbS6{Bhs #include <new>51Testing软件测试网{,y.l'K0J #include <cstdio> 5D"bq8]3h^_g$y0#include <cstdlib>51Testing软件测试网6]@*gcKr #include <string> 6`b)nZ(jq0p(ie6k0using namespace std;51Testing软件测试网;ZK(G BTPm(@ //动态申请二维数组51Testing软件测试网 G2Agb:c2L
\ template <typename T> #@ HE(WU0T** new_Array2D(int row, int col)51Testing软件测试网*p[BJ Y
q D { l@.Ts2d h8l'V0 int size = sizeof(T); /d
K.Z.F7~s0 int point_size = sizeof(T*);
|