如何在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{3pB z^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;
wu1^tQR1o2\e"N0 printf("请输入二维数组的行数(列值固定为%d): ", MAXCOL);51Testing软件测试网u_u2D:[
 scanf("%d", &nRow);
51Testing软件测试网l1u8y3Q-iK#I R0S*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.G kQ3w%c0 {
l+J2T-R0g7f6C m0  for (j = 0; j < MAXCOL; j++)51Testing软件测试网$BCxumP ho;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?/M D

51Testing软件测试网 @TboeO

  详细代码如下,由于指针操作有点小复杂,请读者耐心看:

[wB3Yls6}qK0

8j5xTs:G0
51Testing软件测试网2E I2tdc8o-a*^'E

//C语言中动态的申请二维数组 malloc free
iy2gRYm0#include <stdio.h>51Testing软件测试网3JA Uc.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)\s B7} D
 if (arr != NULL)
9w8W8uM B0m0 { 
/\` q"f2T@ Q x#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&w oy I2k C@$n
 return (T**)arr;51Testing软件测试网-mc4_\SF
}
-u?,G7VFQO0//释放二维数组51Testing软件测试网K9u1G?_ Bu
void free_Aarray2D(void **arr)51Testing软件测试网 \$n h/N'L#F\H U2\7i
{
)i9b`DT0p0 if (arr != NULL)
4C/Wh5G9fbO&J,P9FZ0  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");

4Pd8d N5_8t9N051Testing软件测试网:wZ WB)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{&T N

 //为二维数组赋值 
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!Pu {.~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&K l {:D:G0  putchar('\n');51Testing软件测试网d:` d` d4b;M9Z
 }
51Testing软件测试网`V }]\G4L

51Testing软件测试网1sLxcJ0T:p

 free_Aarray2D((void**)p);
1\;a/NO9pe`g&L1X0 return 0;51Testing软件测试网8v^Nk,jF;Y:l hR.er t
}

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 FNgB

51Testing软件测试网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]@*gc Kr
#include <string>
6`b)nZ(jq0p(ie6k0using namespace std;51Testing软件测试网;ZK(G B TPm(@
//动态申请二维数组51Testing软件测试网G2Agb:c2L \
template <typename T>
#@HE(WU0T** new_Array2D(int row, int col)51Testing软件测试网*p[BJ Y qD
{
l@.Ts2d h8l'V0 int size = sizeof(T);
/d K.Z.F7~s0 int point_size = sizeof(T*);
Ry/O B/XbQy@|0 //先申请内存,其中sizeof(T*) * row表示存放row个行指针
:Xk@0h0`jn[0 T **arr = (T **) malloc(point_size * row + size * row * col);51Testing软件测试网6q&tm7o9ic6@#dS
 if (arr != NULL)51Testing软件测试网l*b&hLyggvt[
 { 
g f;j.uPz7dv3e0  T *head = (T*)((int)arr + point_size * row);
|r1F#R$}0C&g0  for (int i = 0; i < row; ++i)
d-Zc{ g t/S4nT0  {51Testing软件测试网0K'@(ZF tl/K#k8Y
   arr[i] =  (T*)((int)head + i * col * size);
J+yElx*u!F0   for (int j = 0; j < col; ++j)51Testing软件测试网,|o],_ |9PGUD
    new (&arr[i][j]) T;
"fgWDY@&p0  }51Testing软件测试网6RTZ/`$CN
 }
P.P+x!\*T1si0 return (T**)arr;
j iD6\(kmB{'w0}
],X0J!x^ b!z+f b0//释放二维数组51Testing软件测试网 colo-a W
template <typename T>
%}3?H~6UP0void delete_Array2D(T **arr, int row, int col)51Testing软件测试网.q GXFw
{51Testing软件测试网 Mk2btea
 for (int i = 0; i < row; ++i)
Er0V4|1| PWRC*D0  for (int j = 0; j < col; ++j)
}%j]/as X(b1p o0   arr[i][j].~T();51Testing软件测试网$cN Qw+V Nt xs
 if (arr != NULL)51Testing软件测试网q3KQ/\^
  free((void**)arr);51Testing软件测试网9xi K(I ti
}51Testing软件测试网/H*Q1jj(V&khCJ;Y2i9`
int main()
!fR }(]w0{51Testing软件测试网'o"d%Nm4V
 printf("  C++语言中动态的申请二维数组 new delete\n"); 51Testing软件测试网!a#u u(fK
 printf(" -- by MoreWindows( http://blog.csdn.net/MoreWindows ) --\n\n");

N:T'Dr R0u051Testing软件测试网2fKj!Q `0t x6m m9_ @

 printf("请输入行列(以空格分开): ");51Testing软件测试网?#Cs1kJ$w
 int nRow, nCol;51Testing软件测试网 DVW(Ek
 scanf("%d %d", &nRow, &nCol);
51Testing软件测试网fWx!Y([lZg;h

bU#Psb,O$_0 //动态申请连续的二维数组51Testing软件测试网5Zdk3z:WHG[_
 string **p = new_Array2D<string>(nRow, nCol);
51Testing软件测试网&E2j-l0w%R

8x] ^7n&G/|0 //为二维数组赋值
,e$]VF0ebG)o0 int i, j;
N/Kmca? x([0 for (i = 0; i < nRow; i++)51Testing软件测试网Ny Ng,h @ E
  for (j = 0; j < nCol; j++)51Testing软件测试网 q,_u,vR#p"[-f
  {51Testing软件测试网"s8snS a+[O7h
   char szTemp[30];51Testing软件测试网h` |DU w5?,|6w't
   sprintf(szTemp, "(第%d行,第%d列)", i, j);
#AqQX f&e0   p[i][j] = szTemp;
"e,u$`b7zU#J0  }

K;]1WV1dY051Testing软件测试网9}r5H3i7O N4I

 //输出二维数组 
/r'IV$d9Rq wp sc3En0 for (i = 0; i < nRow; i++)
4z J]E2|[(h0 {51Testing软件测试网owETt m.sQv
  for (j = 0; j < nCol; j++)
3GoZ LV h9\3f0   printf("%s ", p[i][j].c_str());51Testing软件测试网*p)F*b~H2^i:B
  putchar('\n');
g z^t(D;W0v@"f0 }

~4dSX?0

~#[a'`K$X0 delete_Array2D<string>(p, nRow, nCol);
Y G;\c,GA0 return 0;
(NdfT)u;yh0}
51Testing软件测试网.j5rc,o_)ps4['l

51Testing软件测试网T$rtF!d.xq~

  运行结果如下:51Testing软件测试网_]R L;CZ s.`

51Testing软件测试网 _ mq:~ n(T8}6w


TAG:

 

评分:0

我来说两句

Open Toolbar