首页 | 互联网 | IT动态 | 网络设备 | 服务器 | IDC | 安全 | Cisco | Windows | Linux | Java | .Net | Oracle | CIW | 华为 | 专题
IT技术 | 网页设计 | 平面设计 | 电子书下载 | 教学视频 | 方案 | 数字网校 | 直播室 | 虚拟考场 | 面授培训 | 搜索 | 博客 | 沙龙 | 论坛
首页 | JAVA | C# | VB | VB.NET | C/C++ | delphi | 工程管理 | 其他语言 | 论坛
免费注册一站通帐号,参与直播、论坛、下载、博客、网摘、评论,展现我的风采!
您现在的位置: 中国IT实验室 >> 桌面开发 >> VC >> 文章正文
如何在C++中动态分配二维数组
来源:中国IT实验室收集整理  时间:2007-8-2

  这个问题应该是我以前在CSDN蹭分时回答次数比较多的一个问题了,我的回答一般是三种方法:(1)用vector的vector,(2)先分配一个指针 数组,然后让里面每一个指针再指向一个数组,这个做法的好处是访问数组元素时比较直观,可以用a[x][y]这样的写法,缺点是它相当于C#中的一个锯齿 数组,内存空间不连续。(3)直接分配一个x*y大小的一维数组,这样保证空间是连续的,但访问数组元素不直观。对于我这个“经典”回答,我那时还一直是 挺得意的,至少从蹭分的角度来看,这样回答还是很有效的。

  今天在ChinaUnix论坛闲逛时看到一个贴子,再次证明了我在C++方面才疏学浅。

  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
  void **darray_new(int row, int col, int size)
  {       
   void **arr;      
   arr = (void **) malloc(sizeof(void *) * row + size * row * col);        if (arr != NULL)      
   {               
       void *head;               
       head = (void *) arr + sizeof(void *) * row;                       memset(arr, 0, sizeof(void *) * row + size * row * col);              while (row--)                       
            arr[row] = head + size * row * col;       
     }       
       return arr;
  }
  void darray_free(void **arr)
  {       
     if (arr != NULL)               
    free(arr);
  }

  嗯,连续分配内存,而且可以用a[x][y]的方式来访问!可谓二维数组动态分配的绝妙方法!这段程序是C的,似乎要改成支持对象分配的C++版也不是什么难事(不过估计得用上placement new吧,嗯,需要再思考一下……)。

  2007-06-13 12:38 补充:

  经过试验,C++版出炉了:)关键点还是在于placement new和显示的析构函数调用,用于保证对象可以正常的构造和析构。
  这个实现也还是有不少缺点的,比如,数组的大小必须记住,才能保证析构所有对象。不过这点可以通过改进分配方法算法,把数组大小也用一点空间保存起来。
  另一个缺点是,从语法上看,很容易让人误把darray_new返回的指针以为是数据区的起始地址,从而可能导致一些逻辑错误。

  #include <iostream>
  #include <cstdlib>
  #include <new>

  template <typename T>
  T **darray_new(int row, int col)
  {
      int size = sizeof(T);
      void **arr = (void **) malloc(sizeof(void *) * row + size * row * col);
      if (arr != NULL)
      {
          unsigned char * head;
          head = (unsigned char *) arr + sizeof(void *) * row;
          for (int i = 0; i < row; ++i)
          {
              arr[i] =  head + size * i * col;
              for (int j = 0; j < col; ++j)
                  new (head + size * (i * col + j)) T;
          }
      }
      return (T**) arr;
  }

  template <typename T>
  void darray_free(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);
  }

【责编:Youping】

中国IT教育热线咨询

相关文章
编程软件系列之C++编程技巧
C++中确定基类有虚析构函数
如何用Delphi实现子目录级的文件查询
如何使用Delphi实现无边界窗体的移动
java 参数是如何传递的
如何用Delphi创建快捷方式
C#的前途如何?
JAVA程序员应当如何来选择RIA的开发环境
推荐文章
· 用C#创建COM对象
· IT管理十大失误及其对策
· VC中利用MFC设计绘图程序初步
· JAVA中对象创建和初始化过程
· C语言中的位域的使用
· 浅谈Java桌面应用程序开发
· C#的前途如何?
· 几种VC++数据库开发技术的相对比较
 精彩友情推荐
·锐捷交换机报价
·锐捷交换机
·锐捷网络网络交换机
·smc交换机
·smc交换机报价
·IDC资讯大全
·机房品质万里行
·IDC托管必备知识
·全国IDC报价
·网站推广优化
最新更新 推荐文章
·Visual Basic 9.0隐式类型的局部…09-30
·JMX+J2SE5.0实现Web应用的安全管…09-30
·多线程、Socket技术及委托技术的…09-21
·Visual C#多线程参数传递浅析09-21
·浅谈Java中利用JCOM实现仿Excel编…09-21
·基于Java的界面布局DSL的设计与实…09-21
·Java开发中的事件驱动模型实例详…09-21
·并发工程原则应用到软件项目中09-06
·Delphi初学者应小心的六大陷阱09-06
·VC开发多语言界面支持的简单方法09-06
·用C#创建COM对象09-06
·用C#创建COM对象09-06
·IT管理十大失误及其对策08-30
·VC中利用MFC设计绘图程序初步08-23
·JAVA中对象创建和初始化过程08-23
·C语言中的位域的使用08-09
·浅谈Java桌面应用程序开发08-09
·C#的前途如何?08-02
·几种VC++数据库开发技术的相对比较07-12
·用Visual C#实现网络封包监视07-12
·VB.NET中的TextBox控件详解07-12
·VB.NET实现PC与掌上电脑PPC的双向通信07-05
  培训中心