如何在C/C++中动态分配二维数组

分享一下我老师大神的人工智能教程!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

如何在C/C++中动态分配二维数组

在C/C++中动态分配二维数组可以先申请一维的指针数组,然后该数组中的每个指针再申请数组,这样就相当于二维数组了,但是这种方法会导致每行可能不相邻,从而访问效率比较低。如何申请连续的二维数组了?本文将分别三个方面讲解:

一.动态申请列大小固定的二维数组

二.C语言中动态申请连续的二维数组

三.C++语言中动态申请连续的二维数组

 

一.动态申请列大小固定的二维数组

首先如果二维数组的列大小固定,那么很简单,可以用申请一维数数组再其指针强制转化成为二维数组指针即可。详见代码:


  
  
  1. //列大小固定的二维数组可以申请一维数据并将指针强转成二维数组
  2. #include <stdio.h>
  3. int main()
  4. {
  5. printf( " 列大小固定的二维数组可以申请一维数据并将指针强转成二维数组\n");
  6. printf( " -- by MoreWindows( http://blog.csdn.net/MoreWindows ) --\n\n");
  7. //列值固定
  8. const int MAXCOL = 3;
  9. int nRow;
  10. printf( "请输入二维数组的行数(列值固定为%d): ", MAXCOL);
  11. scanf( "%d", &nRow);
  12. //申请一维数据并将其转成二维数组指针
  13. int *pp_arr = new int[nRow * MAXCOL];
  14. int (*p)[MAXCOL] = ( int(*)[MAXCOL])pp_arr;
  15. //为二维数组赋值
  16. int i, j;
  17. for (i = 0; i < nRow; i++)
  18. for (j = 0; j < MAXCOL; j++)
  19. p[i][j] = i + j;
  20. //输出二维数组
  21. for (i = 0; i < nRow; i++)
  22. {
  23. for (j = 0; j < MAXCOL; j++)
  24. printf( "%5d", p[i][j]);
  25. putchar( '\n');
  26. }
  27. //释放资源
  28. delete[] pp_arr;
  29. return 0;
  30. }

运行结果如下所示:

 

二.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. //C语言中动态的申请二维数组 malloc free
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. //动态申请二维数组
  6. template < typename T>
  7. T** malloc_Array2D(int row, int col)
  8. {
  9. int size = sizeof(T);
  10. int point_size = sizeof(T*);
  11. //先申请内存,其中point_size * row表示存放row个行指针
  12. T **arr = (T **) malloc(point_size * row + size * row * col);
  13. if (arr != NULL)
  14. {
  15. memset(arr, 0, point_size * row + size * row * col);
  16. T *head = (T*)(( int)arr + point_size * row);
  17. while (row--)
  18. arr[row] = (T*)(( int)head + row * col * size);
  19. }
  20. return (T**)arr;
  21. }
  22. //释放二维数组
  23. void free_Aarray2D(void **arr)
  24. {
  25. if (arr != NULL)
  26. free(arr);
  27. }
  28. int main()
  29. {
  30. printf( " C语言中动态的申请二维数组 malloc free\n");
  31. printf( " -- by MoreWindows( http://blog.csdn.net/MoreWindows ) --\n\n");
  32. printf( "请输入行列(以空格分开): ");
  33. int nRow, nCol;
  34. scanf( "%d %d", &nRow, &nCol);
  35. //动态申请连续的二维数组
  36. int **p = malloc_Array2D< int>(nRow, nCol);
  37. //为二维数组赋值
  38. int i, j;
  39. for (i = 0; i < nRow; i++)
  40. for (j = 0; j < nCol; j++)
  41. p[i][j] = i + j;
  42. //输出二维数组
  43. for (i = 0; i < nRow; i++)
  44. {
  45. for (j = 0; j < nCol; j++)
  46. printf( "%4d ", p[i][j]);
  47. putchar( '\n');
  48. }
  49. free_Aarray2D(( void**)p);
  50. return 0;
  51. }

运行结果如下:

 

 

三.C++语言中动态申请连续的二维数组

可以看出我们已经成功实现了在C语言中动态申请连续的二维数组,如果上面的程序不使用int类型而使用string类这种类型,那会有什么后果了?肯定的说,由于没有调用构造函数和析构函数,程序绝对会造成内存泄露。因此要做下改进,下面给出在C++语言中动态申请连续的二维数组的代码,有些C++语法可能平时见得少,但其实这些语法在STL里面运用还是比较多的,有兴趣的童鞋应该掌握下。


  
  
  1. //C++语言中动态的申请二维数组 new delete
  2. #include <new>
  3. #include <cstdio>
  4. #include <cstdlib>
  5. #include <string>
  6. using namespace std;
  7. //动态申请二维数组
  8. template < typename T>
  9. T** new_Array2D(int row, int col)
  10. {
  11. int size = sizeof(T);
  12. int point_size = sizeof(T*);
  13. //先申请内存,其中sizeof(T*) * row表示存放row个行指针
  14. T **arr = (T **) malloc(point_size * row + size * row * col);
  15. if (arr != NULL)
  16. {
  17. T *head = (T*)(( int)arr + point_size * row);
  18. for ( int i = 0; i < row; ++i)
  19. {
  20. arr[i] = (T*)(( int)head + i * col * size);
  21. for ( int j = 0; j < col; ++j)
  22. new (&arr[i][j]) T;
  23. }
  24. }
  25. return (T**)arr;
  26. }
  27. //释放二维数组
  28. template < typename T>
  29. void delete_Array2D(T **arr, int row, int col)
  30. {
  31. for ( int i = 0; i < row; ++i)
  32. for ( int j = 0; j < col; ++j)
  33. arr[i][j].~T();
  34. if (arr != NULL)
  35. free(( void**)arr);
  36. }
  37. int main()
  38. {
  39. printf( " C++语言中动态的申请二维数组 new delete\n");
  40. printf( " -- by MoreWindows( http://blog.csdn.net/MoreWindows ) --\n\n");
  41. printf( "请输入行列(以空格分开): ");
  42. int nRow, nCol;
  43. scanf( "%d %d", &nRow, &nCol);
  44. //动态申请连续的二维数组
  45. string **p = new_Array2D< string>(nRow, nCol);
  46. //为二维数组赋值
  47. int i, j;
  48. for (i = 0; i < nRow; i++)
  49. for (j = 0; j < nCol; j++)
  50. {
  51. char szTemp[ 30];
  52. sprintf(szTemp, "(第%d行,第%d列)", i, j);
  53. p[i][j] = szTemp;
  54. }
  55. //输出二维数组
  56. for (i = 0; i < nRow; i++)
  57. {
  58. for (j = 0; j < nCol; j++)
  59. printf( "%s ", p[i][j].c_str());
  60. putchar( '\n');
  61. }
  62. delete_Array2D< string>(p, nRow, nCol);
  63. return 0;
  64. }

运行结果如下:

 

 

 

转载请标明出处,原文地址:http://blog.csdn.net/morewindows/article/details/7664479

如果觉得本文对您有帮助,请点击‘顶’支持一下,您的支持是我写作最大的动力,谢谢。



 

这里写图片描述

给我老师的人工智能教程打call!http://blog.csdn.net/jiangjunshow

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值