难道使用AnsiString * 会出问题???
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




