CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
山寨机中的战斗机! 程序优化工程师到底对IT界有没有贡献
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C++ Builder >  基础类

难道使用AnsiString * 会出问题???

楼主MEFULEU(没有作不到,只有想不到)2006-10-18 09:55:12 在 C++ Builder / 基础类 提问

AnsiString   *FieldsName=new   AnsiString   [mFieldsCount+1];  
   
  ...  
   
  delete   []FieldsName;  
  FieldsName=NULL;  
   
  究竟会不会发生内存泄漏啊????????????????? 问题点数:100、回复次数:41Top

1 楼MEFULEU(没有作不到,只有想不到)回复于 2006-10-18 09:55:42 得分 0

据说AnsiString   已经是一个数组?!Top

2 楼MEFULEU(没有作不到,只有想不到)回复于 2006-10-18 10:02:45 得分 0

难道必须这么使用??  
   
        AnsiString   *FieldsName=new   AnsiString   [mFieldsCount+1];  
   
        。。。。。。。。。。  
   
        for   (int   i=0;i<mFieldsCount;i++)  
        {  
              free(&FieldsName[i]);  
        }  
   
        delete   []FieldsName;  
   
  Top

3 楼huzhangyou(信仰(http://www.libing.net.cn))回复于 2006-10-18 10:03:11 得分 10

不管是什么  
  只是一个类  
   
  AnsiString   *FieldsName=new   AnsiString   [mFieldsCount+1];  
  你这样开辟的内存是一个String的数组啊  
  没有问题啊  
  Top

4 楼BlueDeepOcean(蓝色·深海)回复于 2006-10-18 10:38:21 得分 10

利用new声明的,必须用delete进行释放吧,而且如果声明了数组,则必须用[]。因此,不应该存在释放不净的问题。Top

5 楼MEFULEU(没有作不到,只有想不到)回复于 2006-10-18 10:51:34 得分 0

 
  各位老大给我看看  
   
  http://community.csdn.net/Expert/TopicView3.asp?id=5079869Top

6 楼truelove7283159(大头娃娃http://traversite.blog.sohu.com)回复于 2006-10-18 10:58:01 得分 10

你干吗不用StringList。   AnsiString   *   不就是一个StringList。  
  //----------------------------------------------------------  
  俺这样写CODEGUARD也没有报错啊。  
  char   Testa[256]={0};  
  memset(Testa,254,'f');  
  AnsiString   *FieldsName=new   AnsiString   [100];  
   
    for   (int   i=0;i<100;i++)  
    {  
  FieldsName[i]   =   Testa;  
    }  
   
   
   
  delete       []FieldsName;Top

7 楼truelove7283159(大头娃娃http://traversite.blog.sohu.com)回复于 2006-10-18 10:59:34 得分 0

我觉得在给FieldsName[i]   付值一个指针对象的时候要自己单独释放,那个对象然后再delete       []FieldsName;FieldsName=NULL;   应该没有内存泄露。  
   
   
  Top

8 楼jaffy(小胖猫^_^笨猫先飞)回复于 2006-10-18 13:16:48 得分 10

是的,需要释放两次,才可以.  
  相当与指针的指针Top

9 楼BenLeak(摇摆人)回复于 2006-10-18 13:37:20 得分 10

我觉得没有问题呀  
  释放的是数组占用的空间,而   AnsiString   类会自动释放的  
  不过还是建议使用   TStringList   操作Top

10 楼MEFULEU(没有作不到,只有想不到)回复于 2006-10-18 13:37:26 得分 0

to   truelove7283159(大头娃娃)  
   
  报错是不报错,问题是,程序运行时间长了,这个系统内存使用慢慢的增大;  
   
  本来正常为100多m,但是最后竟然超出系统最大内存,  
   
  例如,   内存使用:884776k/732720k;  
   
  那样子就会出问题了;Top

11 楼MEFULEU(没有作不到,只有想不到)回复于 2006-10-18 13:39:25 得分 0

而实际上程序的内存使用最大也就20m左右;  
   
  各个进程,程序使用的内存加起来都没有多少,  
   
  所以我就纳闷那个系统内存使用怎么会变化那么的大!Top

12 楼MEFULEU(没有作不到,只有想不到)回复于 2006-10-18 13:40:39 得分 0

大家有空就看看  
   
  http://community.csdn.net/Expert/TopicView3.asp?id=5079869  
   
  估计都是一样的问题;Top

13 楼wzd268(九霄之鹏)回复于 2006-10-18 14:21:56 得分 0

markTop

14 楼cczlp(不惑)回复于 2006-10-18 15:48:11 得分 10

同意这样:  
  AnsiString   *FieldsName=new   AnsiString   [mFieldsCount+1];  
   
  ....  
   
  for   (int   i=0;i<mFieldsCount+1;i++)  
  {  
        delete   (&FieldsName[i]);  
  }  
  delete   []FieldsName;  
   
  很久以前(3、4年)有过这方面的讨论。  
   
  Top

15 楼FFSB()...()回复于 2006-10-18 17:00:08 得分 10

建议   cczlp试试下面的(会崩溃):  
  //---------------------------------------------------------------------------  
   
  void   __fastcall   TForm1::Timer1Timer(TObject   *Sender)  
  {  
          AnsiString   *P   =   new   AnsiString[10000];  
   
          for(int   I=0;I<10000;I++)  
          {  
                  P[I]   =   I;  
          }  
   
          for(int   I=0;I<10000;I++)  
          {  
                  delete   &P[I];  
          }  
   
          delete[]   P;  
  }  
  Top

16 楼MEFULEU(没有作不到,只有想不到)回复于 2006-10-18 17:24:16 得分 0

to   :FFSB(搞点小资)  
  呵呵,是否是分配的空间太大了,呵呵,我去试一下~~~Top

17 楼MEFULEU(没有作不到,只有想不到)回复于 2006-10-18 17:29:22 得分 0

似乎程序可以运行,并没有崩溃,但是系统所用的内存还是在涨~~~~~~~~Top

18 楼teatool(美貌与智慧并重,英雄与侠义的化身)回复于 2006-10-18 17:31:33 得分 0

字符串用AnsiString  
  很多字符串用TStringListTop

19 楼cczlp(不惑)回复于 2006-10-18 20:06:37 得分 0

TO   FFSB:  
  我试了你的代码,   没有出现崩溃.  
   
  在我机器上代码执行一次大约16ms,   我将Timer的Interval   设为50,   运行大约5分钟,   内存使用也没有异常(泄漏,非法访问).Top

20 楼MEFULEU(没有作不到,只有想不到)回复于 2006-10-19 08:50:33 得分 0

to:BenLeak(摇摆人)     AND   teatool(美貌与智慧并重,英雄与侠义的化身)  
   
  改动位置较多,所以不想动;Top

21 楼hai1039(天下)回复于 2006-10-19 08:58:55 得分 0

建议   cczlp试试下面的(会崩溃):  
  //---------------------------------------------------------------------------  
   
  void   __fastcall   TForm1::Timer1Timer(TObject   *Sender)  
  {  
  AnsiString   *P   =   new   AnsiString[10000];  
   
  for(int   I=0;I<10000;I++)  
  {  
  P[I]   =   I;  
  }  
   
  for(int   I=0;I<10000;I++)  
  {  
  delete   &P[I];  
  }  
   
  delete[]   P;  
  }  
   
  你的意思好象是创建一个长10000字节的AnsiString,   这样P[I]赋值就把stack破坏了,所以崩溃Top

22 楼uhian(豆豆鸟)回复于 2006-10-19 09:03:59 得分 0

mark~~~gz  
  正好我也用了AnsiString,而且还是AnsiString   **。幸好我的数据不是很多。Top

23 楼PPower(月亮光光,照地堂)回复于 2006-10-19 09:14:12 得分 10

AnsiString   *FieldsName=new   AnsiString   [mFieldsCount+1];  
  delete   []   FieldsName ;  
  delete   []會一個個調用AnsiString的析構函數,沒問題。如果用   delete   FieldsName   才有問題。  
   
  這是得到保障的。  
  看這段有問題的代碼   :  
  void   __fastcall   TForm1::Timer1Timer(TObject   *Sender)  
  {  
          AnsiString   *P   =   new   AnsiString[10000];  
   
          for(int   I=0;I<10000;I++)  
          {  
                  P[I]   =   I;  
          }  
   
          for(int   I=0;I<10000;I++)  
          {  
                  delete   &P[I];   //典型的"脫褲子放屁"  
          }  
   
          delete[]   P;   //經過上面的“脫褲子放屁”,此時安全就沒保障了,內存已經被釋放了,再來delete一次,則與使用野指針無異,結果不可預測。不出問題是運氣不差吧。  
  }  
  Top

24 楼cczlp(不惑)回复于 2006-10-19 09:57:50 得分 10

void   __fastcall   TForm1::Timer1Timer(TObject   *Sender)  
  {  
  AnsiString   *P   =   new   AnsiString[10000];  
  for(int   I=0;I<10000;I++)  
  {  
  P[I]   =   I;  
  }  
  delete[]   P;  
  }  
  这段代码看起来没问题吧?试试就知道了,运行一段时间,内存使用逐渐增加。  
  AnsiString类本身有问题。  
   
  (本人只讨论技术)Top

25 楼FFSB()...()回复于 2006-10-19 10:52:06 得分 0

LS怪事  
  我在C++Builder6测试仅程序崩溃.  
  在BDS2006则连BDS2006都死了!  
   
  建议多点人试一下...Top

26 楼jb9802(杰怪)回复于 2006-10-19 11:17:45 得分 0

是不是跟AnsiString类中重载   operator   []有关呀!!Top

27 楼jaffy(小胖猫^_^笨猫先飞)回复于 2006-10-19 11:19:29 得分 0

应该释放两次吧Top

28 楼hai1039(天下)回复于 2006-10-19 11:20:43 得分 10

AnsiStringUnit1.cpp.15:   AnsiString   *P   =   new   AnsiString[10000];  
   
  00401900   68449C0000               push   0x00009c44  
  00401905   E8C64A0500               call   operator   new[](unsigned   int)  
  0040190A   59                               pop   ecx  
  0040190B   8945F8                       mov   [ebp-0x08],eax  
  0040190E   837DF800                   cmp   dword   ptr   [ebp-0x08],0x00  
  00401912   7431                           jz   +0x31  
  00401914   66C745DC2000           mov   word   ptr   [ebp-0x24],0x0020  
  0040191A   681C134600               push   0x0046131c  
  0040191F   6A03                           push   0x03  
  00401921   68341A4000               push   0x00401a34  
  00401926   6813020000               push   0x00000213  
  0040192B   6810270000               push   0x00002710  
  00401930   6A04                           push   0x04  
  00401932   FF75F8                       push   dword   ptr   [ebp-0x08]  
  00401935   E8DA4C0500               call   _vector_new_ldtc_(void   *,unsigned   int,unsigned   int,unsigned   int,void   *,unsigned   int,void   *)  
  0040193A   83C41C                       add   esp,0x1c  
  0040193D   66C745DC1400           mov   word   ptr   [ebp-0x24],0x0014  
  00401943   EB03                           jmp   +0x03  
  00401945   8B45F8                       mov   eax,[ebp-0x08]  
  00401948   8945C0                       mov   [ebp-0x40],eax  
  0040194B   66C745DC0800           mov   word   ptr   [ebp-0x24],0x0008  
   
  AnsiStringUnit1.cpp.16:   for(int   I=0;I<10000;I++)  
   
  00401951   33D2                           xor   edx,edx  
  00401953   8955BC                       mov   [ebp-0x44],edx  
   
  AnsiStringUnit1.cpp.18:   P[I]   =   I;  
   
  00401956   66C745DC2C00           mov   word   ptr   [ebp-0x24],0x002c  
  0040195C   8D45F4                       lea   eax,[ebp-0x0c]  
  0040195F   8B55BC                       mov   edx,[ebp-0x44]  
  00401962   E871F90500               call   System::AnsiString::AnsiString(System::AnsiString   *   const   ,int)  
  00401967   FF45E8                       inc   dword   ptr   [ebp-0x18]  
  0040196A   8D55F4                       lea   edx,[ebp-0x0c]  
  0040196D   8B45BC                       mov   eax,[ebp-0x44]  
  00401970   C1E002                       shl   eax,0x02  
  00401973   0345C0                       add   eax,[ebp-0x40]  
  00401976   E8D1F90500               call   System::AnsiString::operator   =(System::AnsiString   *   const   ,const   System::AnsiString   &)  
  0040197B   FF4DE8                       dec   dword   ptr   [ebp-0x18]  
  0040197E   8D45F4                       lea   eax,[ebp-0x0c]  
  00401981   BA02000000               mov   edx,0x00000002  
  00401986   E891F90500               call   System::AnsiString::~AnsiString(System::AnsiString   *   const   ,int)  
   
  AnsiStringUnit1.cpp.16:   for(int   I=0;I<10000;I++)  
   
  0040198B   FF45BC                       inc   dword   ptr   [ebp-0x44]  
  0040198E   817DBC10270000       cmp   [ebp-0x44],0x00002710  
  00401995   7CBF                           jl   -0x41  
   
  AnsiStringUnit1.cpp.20:   delete[]   P;  
   
  00401997   8B4DC0                       mov   ecx,[ebp-0x40]  
  0040199A   894DF0                       mov   [ebp-0x10],ecx  
  0040199D   66C745DC4400           mov   word   ptr   [ebp-0x24],0x0044  
  004019A3   681C134600               push   0x0046131c  
  004019A8   6A1B                           push   0x1b  
  004019AA   6A00                           push   0x00  
  004019AC   6A04                           push   0x04  
  004019AE   FF75F0                       push   dword   ptr   [ebp-0x10]  
  004019B1   E8FE4A0500               call   _vector_delete_ldtc_(void   *,unsigned   int,unsigned   int,unsigned   int,void   *)  
  004019B6   83C414                       add   esp,0x14  
  004019B9   66C745DC3800           mov   word   ptr   [ebp-0x24],0x0038  
   
  AnsiStringUnit1.cpp.22:   }  
   
  004019BF   8B45CC                       mov   eax,[ebp-0x34]  
  004019C2   64A300000000           mov     fs:[0x00000000],eax  
  004019C8   8B45FC                       mov   eax,[ebp-0x04]  
  004019CB   807DCB00                   cmp   byte   ptr   [ebp-0x35],0x00  
  004019CF   7405                           jz   +0x05  
  004019D1   E817FB0500               call   _AfterConstruction()  
   
  AnsiStringUnit1.cpp.22:   }  
   
  004019D6   8BE5                           mov   esp,ebp  
  004019D8   5D                               pop   ebp  
  004019D9   C3                               ret    
  004019DA   90                               nop    
  004019DB   90                               nop    
  *,int)  
   
  Top

29 楼hai1039(天下)回复于 2006-10-19 11:33:52 得分 0

//---------------------------------------------------------------------------  
   
  #include   <vcl.h>  
  #pragma   hdrstop  
   
  #include   "AnsiStringUnit1.h"  
  //---------------------------------------------------------------------------  
  #pragma   package(smart_init)  
  #pragma   resource   "*.dfm"  
  TForm1   *Form1;  
  //---------------------------------------------------------------------------  
  __fastcall   TForm1::TForm1(TComponent*   Owner)  
          :   TForm(Owner)  
  {  
          while(1)  
          {  
                  AnsiTest();  
          }  
   
  }  
  //---------------------------------------------------------------------------  
   
  __fastcall   TForm1::AnsiTest(void)  
  {  
  AnsiString   *P   =   new   AnsiString[10000];  
  for(int   I=0;I<10000;I++)  
  {  
  P[I]   =   I;  
  }  
  delete[]   P;  
   
  }  
   
  winxp,   BCB6.0   sp4,   debug/release运行10分钟都没见明显内存泄露,  
  taskmanager里内存占用一直不到3M.  
   
  恐怕是你们代码其它地方有冲突,或者你们的c++   builder版本问题?Top

30 楼FFSB()...()回复于 2006-10-19 11:37:37 得分 0

hai1039(天下)你上面的代码没有问题.(运行1小时后没有发生内存问题)  
  问题是cczlp的代码测试出问题?Top

31 楼MEFULEU(没有作不到,只有想不到)回复于 2006-10-19 13:36:02 得分 0

呵呵,我搬凳子,静听~~~~~~~~~~~~~~~Top

32 楼cczlp(不惑)回复于 2006-10-19 16:44:14 得分 0

我运行不到3分钟,内存占用增加了几十K,   虚拟内存不变。  
   
  //---------------------------------------------------------------------------  
   
  #include   <vcl.h>  
  #pragma   hdrstop  
   
  #include   "Unit1.h"  
  //---------------------------------------------------------------------------  
  #pragma   package(smart_init)  
  #pragma   resource   "*.dfm"  
  TForm1   *Form1;  
  //---------------------------------------------------------------------------  
  __fastcall   TForm1::TForm1(TComponent*   Owner)  
          :   TForm(Owner)  
  {  
  Timer1->Interval   =   50;  
  }  
  //---------------------------------------------------------------------------  
   
  void   __fastcall   TForm1::Timer1Timer(TObject   *Sender)  
  {  
  AnsiString   *P   =   new   AnsiString[10000];  
  for(int   I=0;I<10000;I++)  
  {  
  P[I]   =   I;  
  }  
  delete[]   P;  
  }  
  //---------------------------------------------------------------------------  
  Top

33 楼PPower(月亮光光,照地堂)回复于 2006-10-20 08:14:40 得分 0

還是不用Timer1->Interval   =   50;來測試吧。  
  Timer定時不准,50ms說不定20ms就發生了該事件   ,很難說事件能執行完成。因為一直申請內存,部分事件在Timer1的時間內來不及釋放,導致內存上漲。timer停止後內存將恢復正常。  
   
  void   __fastcall   TForm1::BitBtn1Click(TObject   *Sender)  
  {  
    BitBtn1->Enabled   =   false   ;  
    int   count   =   1     ;  
    while(   count   >   0   )  
    {  
        AnsiString   *P   =   new   AnsiString[10000];  
        for(int   I=0;I<10000;I++)  
  {  
  P[I]   =   I;  
  }  
  delete[]   P;  
        ++count;  
        Caption   =   IntToStr(count)   ;   //發貼時   Caption   =   10W   次了  
    }  
    BitBtn1->Enabled   =   true   ;  
  }  
   
  我特意在BCB2006中測試了一下,不出問題,程序占用的內存穩定在一個值7092K上,沒有變化Top

34 楼wt_sanlian(雷电)回复于 2006-10-20 08:24:05 得分 0

个人认为这样用没问题Top

35 楼PPower(月亮光光,照地堂)回复于 2006-10-20 08:34:14 得分 0

//如果是要用timer作測試,考慮下面的代碼  
  多加個全局變量,可以防止因為Timer定時不准帶來的問題。  
  bool   Lock   =   false   ;      
  void   __fastcall   TForm1::Timer1Timer(TObject   *Sender)  
  {  
  if(Lock)  
      return   ;  
  Lock   =   true   ;    
  AnsiString   *P   =   new   AnsiString[10000];  
  for(int   I=0;I<10000;I++)  
  {  
  P[I]   =   I;  
  }  
  delete[]   P;  
  Lock   =   false   ;    
  }  
  //在多次的new   delete後,系統可能會自動的調整內存頁,在某個時刻,new或delete的速度比平時要慢上很多。這就使得用Timer來測試帶來不確定性。  
  Top

36 楼xiaoshi0(Rain)回复于 2006-10-20 09:59:44 得分 0

AnsiString   *pStr   =   new   AnsiString[100];  
  delete[]   pStr;  
   
  以上的语句一点问题都没有。  
   
  AnsiString   *pStr   =   new   AnsiString[100];  
  for   (int   i   =   0;   i   <   100;   i++)         //这个循环没有作用  
  {  
          delete   &pStr[i];  
  }  
  delete[]   pStr;  
   
  首先要知道AnsiString是一个字符串(char*)的封装,但我们这样声明一个AnsiString的对象时  
   
  AnsiString   str;  
   
  等于我们调用无参构造函数构造该对象,AnsiString对象中的char*成员变量为NULL,没有分配内存,当你赋值的时候,AnsiString对象才分配足够大的内存,并且将你值copy到char*成员变量中。  
   
  而上面的例子,当调用delete   &pStr[i]时,仅仅是将其中一个AnsiString对象给删除了,但pStr这个指针还是没有清除。  
   
  而在调用delete[]   pStr的时候,系统会自动调用对象的析构函数,同样也会删除掉AnsiString对象分配的内存。  
   
  所以即使不用for循环调用,一样可义达到效果。至于为什么内存会增大,个人认为和这个方法没有直接的关系。具体的我在另一个帖子中说明。Top

37 楼cczlp(不惑)回复于 2006-10-20 11:35:14 得分 0

AnsiString   *pStr   =   new   AnsiString[100];  
  delete[]   pStr;  
  在语法上没有问题。我是怀疑AnsiString   类本身的实现存在内存泄漏的情况。  
  没有确定,只是怀疑。Top

38 楼cczlp(不惑)回复于 2006-10-20 11:55:00 得分 0

这个程序在我PC上占用CPU   55%,程序运行后占用内存6180,   3分钟后占用内存6200,  
  又过几分钟,占用内存6208,然后就没继续观察。  
   
  用CB6+UP4,   XP+SP2,测试。  
   
  我不是说语法问题,只是为了弄明白AnsiString类到底有没有BUG   。  
   
  //---------------------------------------------------------------------------  
   
  #include   <vcl.h>  
  #pragma   hdrstop  
   
  #include   "Unit1.h"  
  //---------------------------------------------------------------------------  
  #pragma   package(smart_init)  
  #pragma   resource   "*.dfm"  
  TForm1   *Form1;  
  //---------------------------------------------------------------------------  
  __fastcall   TForm1::TForm1(TComponent*   Owner)  
          :   TForm(Owner)  
  {  
  }  
  //---------------------------------------------------------------------------  
   
  BOOL     bExit   =   false;    
  void   __fastcall   TForm1::Button1Click(TObject   *Sender)  
  {  
          while   (!bExit)  
          {  
                  AnsiString   *P   =   new   AnsiString[10000];  
                  for(int   I=0;I<10000;I++)  
                  {  
                  P[I]   =   I;  
                  }  
                  delete[]   P;  
   
                  Application->ProcessMessages();   //防止程序没反应  
                  Sleep(10);  
          }  
   
  }  
  //---------------------------------------------------------------------------  
  void   __fastcall   TForm1::FormClose(TObject   *Sender,   TCloseAction   &Action)  
  {  
            bExit   =   true;  
  }  
  //---------------------------------------------------------------------------  
  Top

39 楼MEFULEU(没有作不到,只有想不到)回复于 2006-10-20 16:43:06 得分 0

这个问题,似乎没有结果了~Top

40 楼zswang(伴水清清)(专家门诊清洁工)回复于 2006-10-20 16:51:48 得分 0

不会有泄漏  
  上面的测试已经证明了  
  Top

41 楼MEFULEU(没有作不到,只有想不到)回复于 2006-10-20 17:00:58 得分 0

谢谢各位交流,分数太少了,不够分,大家要分到我另一个贴来;  
   
  http://community.csdn.net/Expert/TopicView3.asp?id=5079869Top

相关问题

关键词

得分解答快速导航

  • 帖主:MEFULEU
  • huzhangyou
  • BlueDeepOcean
  • truelove7283159
  • jaffy
  • BenLeak
  • cczlp
  • FFSB
  • PPower
  • cczlp
  • hai1039

相关链接

  • CSDN Blog
  • 技术文档
  • 代码下载
  • 第二书店
  • 读书频道

广告也精彩

反馈

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