主執行緒通過定時器每秒觸發一次子執行緒Sig_Collect,程式運行一段時間就提示“...raised exception class std::bad_alloc with message ...”。CodeGuard沒有提示記憶體泄露。但是打開任務管理器發現占用的記憶體不斷攀升,一次增加16KB或者32KB,實在是找不出哪里在泄露,該delete的都delete了。執行緒執行到Execute的最后一行不就自動退出了嗎??應該不需要顯式的釋放執行緒資源吧?
子執行緒在定時器里建立
void __fastcall TDataAcquireMainForm::Timer1sTimer(TObject *Sender)下面是執行緒的Execute函式體
{
Sig_Collect(false);//Sig_Collect為創建的執行緒
}
void __fastcall Sig_Collect::Execute()
{
//---- Place thread code here ----
FreeOnTerminate=true;
OnTerminate=DataAcquireMainForm->OnOverThread;
SiandWr->Acquire();//臨界區
if(CacheSize>=1800)
{
if(Ev->WaitFor(INFINITE)==wrSignaled)//執行緒同步
{
DeleteFile(DataDir+"DataCache\\Data.dat");
CacheSize=0;
Ev->ResetEvent();
}
else
return;
}
double dt=1.0/n_Fre;//時間增量
double *fData=https://bbs.csdn.net/topics/new double[n_FChannel-n_FHChannel];//一維陣列
double *sData=https://bbs.csdn.net/topics/new double[n_SChannel];//一維陣列
double **ffData=https://bbs.csdn.net/topics/(double **)new double *[n_FChannel-n_FHChannel];//二維陣列
for(int i=0;i<n_FChannel-n_FHChannel;i++)
ffData[i]=new double[n_Fre];
int File;//檔案句柄
if(FileExists(DataDir+"DataCache\\Data.dat"))
File=FileOpen(DataDir+"DataCache\\Data.dat",fmOpenWrite|fmShareDenyWrite);
else
File=FileCreate(DataDir+"DataCache\\Data.dat");
FileSeek(File,0,2);
if(n_FChannel-n_FHChannel)
{
int nf=n_time%20;
for(int k=nf*n_Fre;k<(nf+1)*n_Fre;k++)
{
for(int i=0;i<n_FChannel-n_FHChannel;i++)
{
fData[i]=DataEngine(false,i,dt*k,n_Fre);
ffData[i][k-nf*n_Fre]=fData[i];
}
FileWrite(File,fData,(n_FChannel-n_FHChannel)*sizeof(double));
}
int minu=CacheSize/60;
int sec=CacheSize%60;
AnsiString datapointer=NULL;
double FieldValue[8];
int n_fre[6];//各倍頻所在的頻率
double BFre[6];//基頻幅值
for(int i=0;i<n_FChannel-n_FHChannel;i++)
{
datapointer=String(minu)+":"+String(sec);
FieldValue[0]=FormatFloat("00.000",max(ffData[i],n_Fre)).ToDouble();
FieldValue[1]=FormatFloat("00.000",min(ffData[i],n_Fre)).ToDouble();
FieldValue[2]=FormatFloat("00.000",jfgen(ffData[i],n_Fre)).ToDouble();
FieldValue[3]=FormatFloat("00.000",fcha(ffData[i],n_Fre)).ToDouble();
FieldValue[4]=FormatFloat("00.000",piancha(ffData[i],n_Fre)).ToDouble();
FieldValue[5]=FormatFloat("00.000",qiaodu(ffData[i],n_Fre)).ToDouble();
FieldValue[6]=FormatFloat("00.000",fzhi(ffData[i],n_Fre)).ToDouble();
FieldValue[7]=FormatFloat("00.000",sfzhi(ffData[i],n_Fre)).ToDouble();
DateSeparator='/';
TimeSeparator=':';
strsql.sprintf("INSERT INTO 時域特征值表 (通道名,高頻,時間,資料指標,最大值,最小值,均方根值,方差,偏差,峭度,峰值,峰峰值) VALUES ('%s','False','%s','%s','%6.3f','%6.3f','%6.3f','%6.3f','%6.3f','%6.3f','%6.3f','%6.3f')",
NameFCha[i],DataTime.DateTimeString(),datapointer,FieldValue[0],FieldValue[1],FieldValue[2],FieldValue[3],FieldValue[4],FieldValue[5],FieldValue[6],FieldValue[7]);
Synchronize(CalcuEigen);//呼叫主界面的TADO組件,使用同步方法
rfftbase2(ffData[i],n_Fre);
BFre[1]=ffData[i][0];
for(int k=0;k<n_Fre/2;k++)
{
if(BFre[1]<ffData[i][k])
{
BFre[1]=ffData[i][k];
n_fre[1]=k;
}
}
n_fre[0]=n_fre[1]/2;n_fre[2]=2*n_fre[1];n_fre[3]=3*n_fre[1];n_fre[4]=4*n_fre[1];n_fre[5]=5*n_fre[1];
for(int k=0;k<6;k++)
{
if(n_fre[k]>n_Fre/2-1)
n_fre[k]=n_Fre/2-1;
BFre[k]=ffData[i][n_fre[k]];
}
DateSeparator='/';
TimeSeparator=':';
strsql.sprintf("INSERT INTO 頻域特征值表 (通道名,高頻,時間,資料指標,[1/2倍頻],主頻,[2倍頻],[3倍頻],[4倍頻],[5倍頻]) VALUES ('%s','False','%s','%s','%6.3f','%6.3f','%6.3f','%6.3f','%6.3f','%6.3f')",
NameFCha[i],DataTime.DateTimeString(),datapointer,BFre[0],BFre[1],BFre[2],BFre[3],BFre[4],BFre[5]);
Synchronize(CalcuEigen);//呼叫主界面的TADO組件,使用同步方法
}
}
if(n_SChannel)
{
for(int i=0;i<n_SChannel;i++)
sData[i]=DataEngine(true,i,n_time,0);
FileWrite(File,sData,n_SChannel*sizeof(double));
}
FileClose(File);
if((n_FChannel-n_FHChannel)||n_SChannel)
{
HWND pWnd=FindWindow("TMonitorForm","監測畫面");
if(pWnd)
SendMessage(pWnd,WM_MONITOR,1,0);
n_time++;
CacheSize++;
}
delete[] fData;
delete[] sData;
for(int i=0;i<n_FChannel-n_FHChannel;i++)
delete[] ffData[i];
delete[] ffData;
SiandWr->Release();//釋放臨界區
n_end_Sig=true;
}
uj5u.com熱心網友回復:
把Execute中的代碼段依次屏蔽一部分,看看相應是否存在記憶體泄露,判斷泄露出自那個部分,有時候還可能并不出在Execute中uj5u.com熱心網友回復:
打開任務管理器,我發現行程使用的句柄數在不斷飆升uj5u.com熱心網友回復:
你有兩次檔案打開類操作,但只有一次檔案關閉。uj5u.com熱心網友回復:
那兩句話放在if-else里面,一次只會執行一句的。uj5u.com熱心網友回復:
這種情況建議不要在每次在定時器中生成一個新的執行緒,而是只有一個業務執行緒,然后在定時器中通過事件變數去觸發這個業務執行緒,這樣會合理不少uj5u.com熱心網友回復:
謝謝!uj5u.com熱心網友回復:
1 拿出來單獨測驗 2 執行緒只用來執行任務 3 資源申請、釋放放到外部。轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/117228.html
標籤:基礎類
上一篇:新人c++求教,求大神幫助
