CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
不看会后悔的Windows XP之经验谈 简单快捷DIY实用家庭影院
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  VC/MFC >  基础类

动态数组与静态数组哪个内存占的多?

楼主taojinkuang(淘金狂)2006-10-18 10:16:30 在 VC/MFC / 基础类 提问

我修改一个程序,原来的程序是这样的:  
  typedef   struct   A  
  {  
          int   a;  
          long   b;  
          long   c[30];  
  }  
  CArray<A,A>   m_arrayA;  
  在某个函数中,这样往系统中存数据  
  A m_a;  
  for(int   i=0;i<800000;i++)  
  {  
        m_a.a=1;  
        m_a.b=2;  
        m_arrayA.Add(m_a)  
  }  
  上面的程序在98系统下跑,没出错;  
  我现在修改如下:  
  typedef   struct   A  
  {  
          int   a;  
          long   b;  
          vector<long>   c;//修改了该处  
  }  
  CArray<A,A>   m_arrayA;  
  在某个函数中,这样往系统中存数据  
  A m_a;  
  for(int   i=0;i<800000;i++)  
  {  
        m_a.a=1;  
        m_a.b=2;  
        m_arrayA.Add(m_a)  
  }  
  改成了这样,在98系统下跑却提示内存不足??  
   
  为什么啊??? 动态的不是应该比静态的省内存吗?给点意见吧  
  问题点数:20、回复次数:39Top

1 楼syy64(太平洋)回复于 2006-10-18 10:20:38 得分 0

因为你结构已变了,占得内存增大了。Top

2 楼ripyu(抢分的恶狼)回复于 2006-10-18 10:25:43 得分 0

第2个结构比第一个结构的占的内存大了很多Top

3 楼taojinkuang(淘金狂)回复于 2006-10-18 10:27:08 得分 0

我的结构体里把静态改为动态,原则上应该节省内存的啊.long   c[30]每次往m_arrayA中压入的数据应该是30*4+其他变量 的长度的字节.  而改了之后的长度应该小于之前啊?怎么回事啊?Top

4 楼taojinkuang(淘金狂)回复于 2006-10-18 10:28:53 得分 0

它为什么大了很多呢?跟我详细说说吧!Top

5 楼taojinkuang(淘金狂)回复于 2006-10-18 10:31:46 得分 0

我要怎样改进我第一个结构体让他占用更少的内存呢?  
  存到结构体中的树组中的数据不是固定的,但最多有30条,程序该怎样改进呢???Top

6 楼ripyu(抢分的恶狼)回复于 2006-10-18 10:32:19 得分 0

建议看看vectorTop

7 楼bobob(静思)回复于 2006-10-18 10:35:57 得分 0

template<class   T,   class   A   =   allocator<T>   >  
          class   vector   {  
  public:  
          typedef   A   allocator_type;  
          typedef   A::size_type   size_type;  
          typedef   A::difference_type   difference_type;  
          typedef   A::reference   reference;  
          typedef   A::const_reference   const_reference;  
          typedef   A::value_type   value_type;  
          typedef   T0   iterator;  
          typedef   T1   const_iterator;  
          typedef   reverse_iterator<iterator,   value_type,  
                  reference,   A::pointer,   difference_type>  
                          reverse_iterator;  
          typedef   reverse_iterator<const_iterator,   value_type,  
                  const_reference,   A::const_pointer,   difference_type>  
                          const_reverse_iterator;  
          explicit   vector(const   A&   al   =   A());  
          explicit   vector(size_type   n,   const   T&   v   =   T(),   const   A&   al   =   A());  
          vector(const   vector&   x);  
          vector(const_iterator   first,   const_iterator   last,  
                  const   A&   al   =   A());  
          void   reserve(size_type   n);  
          size_type   capacity()   const;  
          iterator   begin();  
          const_iterator   begin()   const;  
          iterator   end();  
          iterator   end()   const;  
          reverse_iterator   rbegin();  
          const_reverse_iterator   rbegin()   const;  
          reverse_iterator   rend();  
          const_reverse_iterator   rend()   const;  
          void   resize(size_type   n,   T   x   =   T());  
          size_type   size()   const;  
          size_type   max_size()   const;  
          bool   empty()   const;  
          A   get_allocator()   const;  
          reference   at(size_type   pos);  
          const_reference   at(size_type   pos)   const;  
          reference   operator[](size_type   pos);  
          const_reference   operator[](size_type   pos);  
          reference   front();  
          const_reference   front()   const;  
          reference   back();  
          const_reference   back()   const;  
          void   push_back(const   T&   x);  
          void   pop_back();  
          void   assign(const_iterator   first,   const_iterator   last);  
          void   assign(size_type   n,   const   T&   x   =   T());  
          iterator   insert(iterator   it,   const   T&   x   =   T());  
          void   insert(iterator   it,   size_type   n,   const   T&   x);  
          void   insert(iterator   it,  
                  const_iterator   first,   const_iterator   last);  
          iterator   erase(iterator   it);  
          iterator   erase(iterator   first,   iterator   last);  
          void   clear();  
          void   swap(vector   x);  
  protected:  
          A   allocator;  
          };  
   
  你看看哪个大Top

8 楼wf520pb()回复于 2006-10-18 10:46:37 得分 0

#include   "stdafx.h"  
  #include   <vector>  
  #include   <afxtempl.h>  
  using   namespace   std;  
   
   
  struct   A  
  {  
          int   a;  
          long   b;  
          vector<long>c;  
  };  
  CArray<A,A>   m_arrayA;  
   
   
  int   main(int   argc,   char*   argv[])  
  {  
  A   m_a;  
  for(int   i=0;i<8000;i++)  
  {  
  m_a.a=1;  
  m_a.b=2;  
  m_arrayA.Add(m_a);  
  }  
  printf("Sizeof:%d!\n",sizeof(vector<long>));  
  system("PAUSE");  
  return   0;  
  }  
  内存2176  
   
   
   
  #include   "stdafx.h"  
  #include   <vector>  
  #include   <afxtempl.h>  
  using   namespace   std;  
   
   
  struct   A  
  {  
          int   a;  
          long   b;  
          long   c[30];  
  };  
  CArray<A,A>   m_arrayA;  
   
   
  int   main(int   argc,   char*   argv[])  
  {  
  A   m_a;  
  for(int   i=0;i<8000;i++)  
  {  
  m_a.a=1;  
  m_a.b=2;  
  m_arrayA.Add(m_a);  
  }  
  printf("Sizeof:%d!\n",sizeof(vector<long>));  
  system("PAUSE");  
  return   0;  
  }  
  内存3076  
   
  ==============================================  
  XP   +   VC6Top

9 楼wf520pb()回复于 2006-10-18 10:53:43 得分 0

bobob(静思)   (   )    
  ===============================  
  我想说的是,一个类的函数,他无论有多是个对象,  
  在调用相同函数时,都是去一个地址上访问的。  
  不会有很多内存去给每个对象的函数分配内存地址。  
   
  之所以调用会不同:  
  只是根据传过去的this来得知处理的是哪个对象的数据?  
   
  你可以试如下代码:  
  #include   "stdafx.h"  
   
  class   A  
  {  
  public:  
  void   print()  
  {  
  static   int   i=0;  
  printf("%d\n",i);  
  i++;  
  }  
  };  
   
  A   a1;  
  A   a2;  
  int   main(int   argc,   char*   argv[])  
  {  
  a1.print();  
  a2.print();  
  printf("Hello   World!\n");  
  return   0;  
  }  
  结果就是:  
  0  
  1Top

10 楼taojinkuang(淘金狂)回复于 2006-10-18 11:08:54 得分 0

很感激大家,但我还不是很懂?Top

11 楼taojinkuang(淘金狂)回复于 2006-10-18 11:22:55 得分 0

大家继续讨论啊?我还不明白啊?Top

12 楼taojinkuang(淘金狂)回复于 2006-10-18 11:25:35 得分 0

我的程序怎样改节省内存啊???Top

13 楼vcPlayer(没有星星,努力做太阳!)回复于 2006-10-18 13:13:02 得分 0

动态数组要比相同大小的静态数组多占用一个int型的空间.Top

14 楼bobob(静思)回复于 2006-10-18 14:26:51 得分 0

类的成员变量有单独的空间吧?  
  类里面要有记录函数地址的指针吧?这个指针是否是本进程空间我就不知道了,但是绝对要有的.  
   
  Top

15 楼taojinkuang(淘金狂)回复于 2006-10-18 14:51:32 得分 0

我把定长数组改成变长数组的目的是节省内存空间,用这种方法看来是不行了,那我该怎样实现我的功能呢,大家给点建议吧!!Top

16 楼bobob(静思)回复于 2006-10-18 15:49:29 得分 0

定义成long类型的指针,用的时候再分配空间  
  typedef   struct   A  
  {  
          int   a;  
          long   b;  
          long   *c;  
  }Top

17 楼w_anthony()回复于 2006-10-18 19:37:51 得分 0

动态只是看似动态,vector有个reserve用来预留空间,也就是说就算动态数组里面元素没满,但仍要预留出空间,并没有因此节省了内存。如果要每次大小都刚刚好,不浪费一点一滴,那么在添加元素的时候就要付出相应的“分配新空间、复制数据、删除原空间”的代价,显然这是很不合算的。计算机本身处理数据的方式就是那样,任何所说的动态数组只是对外部程序员而言罢了……Top

18 楼roscoe(草上飞)回复于 2006-10-18 22:48:40 得分 0

那就学习SDK中结构的做法.  
  在SDK中很多结构往往最后一个参数是   WORD   xxxx[1];之类.  
  分配时是该结构加上xxxxx的实际字节.  
  例子:  
    struct   ToolBarData  
    {  
            WORD       wCount;  
            WORD       wIDs[1];  
    }  
    假如有10个ID时.  
    BYTE   *   pData   =   (BYTE*)malloc(   sizeof(ToolBarData)+   (10-1)*   sizeof(WORD)   );  
   
  为什么wIDs不使用指针而是数组,是因为那会多开销一个指针,在使用中增加了验证指针有效性  
   
  所以结构体改成  
  typedef   struct   A  
  {  
          int   a;  
          long   b;  
          UINT   Count;  
          long   c[1];  
  }  
  //  
  不过这也导致编程复杂度增加.  
  CArray中就不能使用结构体作为模板参数了,因为这个结构本是变长的.你只有使用结构体指针了  
  Top

19 楼roscoe(草上飞)回复于 2006-10-18 22:56:51 得分 0

数组类的缺点上面已有说明,不再多说,但你一次要分配800000那你可以考虑字段类型是不是非得用int型,能不能用BYTE,WORD等更小的类型替代.不行就试试数据可不可以压缩成BYTE或WORD  
  返正要省内存就要在代码上考虑Top

20 楼Super_007AtChina()回复于 2006-10-19 12:47:30 得分 0

改成动态分配内存方式在有些时候是可以节省内存的,但在你的使用当中,你首先得考虑对动态分配的内存如何回收,这样的话,如果处理不好容易造成内存泄漏或者增加程序负担。你得抉择。  
      如果不考虑以上这些,那么你可以在结构体中定义成char*类型,使用的时候外部先动态分配好实际使用大小的内存,然后再把指针指向这块内存就好了。不过切记做好内存的回收工作。Top

21 楼coldleafzl()回复于 2006-10-19 15:48:40 得分 0

路过,学习,佩服各位大大Top

22 楼crcr(游侠)回复于 2006-10-19 16:03:47 得分 0

因为你结构已变了,占得内存增大了Top

23 楼xdlous(虾米螺丝)回复于 2006-10-19 16:06:28 得分 0

vector要先申请一定的内存的Top

24 楼fengfeiwuwq(寒烟翠)回复于 2006-10-20 12:10:45 得分 0

vector是模板类,分配的内存比普通数组大得多Top

25 楼xing_dragon(*龙)回复于 2006-10-20 12:56:38 得分 0

vector一开始是分配256个对象的内存,  
  如果vector中加入的对象达到256比如在增加一个的话,它会去申请一个2*256的内存并把当前数据复制过去,在释放当前的内存.  
  所以你的程序中不断的申请,释放,申请的同时等于要求系统有2倍当前大小的内存.  
  插入的数据越多,要求的内存就越大,所以会失败.  
  -------------个人意见,不正确欢迎大家指出Top

26 楼cxjddd(又是花开时)回复于 2006-10-20 13:18:17 得分 0

sizeof(vector<long>)   是不会大的,一般只有几倍于   sizeof(int)。  
  相对于   vector<long>   本身的大小来说,可能更严重是   vector   分配所造成的内存碎片;而   long[]   型的数组相对要少一片内存的使用。Top

27 楼hnucnn()回复于 2006-10-20 13:34:47 得分 0

原因很简单,因为VECTOR函数本身会预留一些空间,表面上你好象是用动态数组比静态数组省空间,其实,你每次存数据时候,都会多开辟那些预留空间,实际上是使内存开销更大。Top

28 楼mousetan(mousetan)回复于 2006-10-20 13:43:24 得分 0

原因很简单,因为VECTOR函数本身会预留一些空间,表面上你好象是用动态数组比静态数组省空间,其实,你每次存数据时候,都会多开辟那些预留空间,实际上是使内存开销更大。  
   
  这个解释应该是对的,可以看看STL的源代码分析之类的,看看如何分配内存的就知道了Top

29 楼trueadou(木头龙)回复于 2006-10-20 13:48:37 得分 0

学习~Top

30 楼wlwlxj(wlwlxj)回复于 2006-10-20 14:26:52 得分 0

vector是以2的倍数增长内存,所以30大小的时候分配32实际大小,这样可以避免频繁搬动内存浪费时间还有导致内存碎片Top

31 楼snwcwt(风舞影天)回复于 2006-10-20 17:56:06 得分 0

类的成员变量有单独的空间吧?  
  类里面要有记录函数地址的指针吧?这个指针是否是本进程空间我就不知道了,但是绝对要有的.  
  ====C++的对象模型中,函数是不会占类实例的空间,函数地址的指针不是分别保存在每个实例对象中的,推荐你去看下   inside   the   c++   object   modelTop

32 楼losedxyz(我真的一无所有)回复于 2006-10-22 00:07:34 得分 0

markTop

33 楼asdfqwer1111(wang)回复于 2006-10-22 16:05:48 得分 0

typedef   struct   A  
  {  
          int   a;  
          long   b;  
          long   c[30];  
  }大小应该是30×sizeof(long)×3   吧      
  可以用#pargma   pack()减少  
   
  for(int   i=0;i<800000;i++)           i最大多少?   程序不是作秀的Top

34 楼zmzbs123(小阵阵)回复于 2006-10-23 12:33:22 得分 0

markTop

35 楼cnkit(山外山)回复于 2006-10-23 22:35:31 得分 0

typedef   struct   A  
  {  
          long   c[30];  
          int   a;  
          long   b;  
  };  
   
  应该是从大到小吧Top

36 楼kkwwkk16(上帝之手)回复于 2006-10-23 22:42:59 得分 0

动态大Top

37 楼domino_question()回复于 2006-10-23 23:32:13 得分 0

动态大.   因为动态的需要预分配空间.   而且动态的效率不如静态Top

38 楼yujia120(永不停息)回复于 2006-10-24 00:26:09 得分 0

不能一概而论,和作用域也有关系Top

39 楼bbbg()回复于 2006-10-24 11:03:07 得分 0

稀里糊涂中Top

相关问题

关键词

得分解答快速导航

  • 帖主:taojinkuang

相关链接

  • Visual C++类图书
  • Visual C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo