2013-06-13 50 views
0

我在寫一個使用c代碼的matlab mex函數。我在釋放分配的內存時遇到了一些麻煩。我在遇到以下代碼時遇到問題。如果我擺脫所有的免費()行,代碼的作品,但我有內存泄漏。這意味着代碼在內存不足之前只能運行幾次。所有調用的函數都有指針作爲輸入,所以我從不改變函數內指針的地址。我在內存分配/釋放過程中犯了錯誤嗎?動態內存分配和內存泄漏

void RLS_(int *M, int *N, double *h, double *y, double *P, double *theta) 
{ 

int i; 
double *Ph;//[*M]; 
double hPh; 
double inv; 
double *inv1; 
double *invPh;//[*M]; 
double *hTtheta;//[*N]; 
double *ymhTtheta;//[*N]; 
double **ADD;//[*M][*N]; 
double **invPhhT;//[*M][*M]; 
double **SUB;//[*M][*M]; 

Ph = (double *) malloc (*M * sizeof(double)); 
if (Ph == NULL) 
    return; 

invPh = (double *) malloc (*M * sizeof(double)); 
if (invPh == NULL) 
    return; 

hTtheta = (double *) malloc (*N * sizeof(double)); 
if (hTtheta == NULL) 
    return; 

ymhTtheta = (double *) malloc (*N * sizeof(double)); 
if (ymhTtheta == NULL) 
    return; 

ADD = (double **) malloc (*M * sizeof(double *)); 
if (ADD == NULL) 
    return; 
for (i=0;i<*M;i++) 
{ 
    ADD[i] = (double *) malloc(*N *sizeof(double)); 
    if (ADD[i] == NULL) 
     return; 
} 
invPhhT = (double **) malloc (*M * sizeof(double *)); 
if (invPhhT == NULL) 
    return; 
for (i=0;i<*M;i++) 
{ 
    invPhhT[i] = (double *) malloc(*M *sizeof(double)); 
    if (invPhhT[i] == NULL) 
     return; 
} 
SUB = (double **) malloc (*M * sizeof(double *)); 
if (SUB == NULL) 
    return; 
for (i=0;i<*M;i++) 
{ 
    SUB[i] = (double *) malloc(*M *sizeof(double)); 
    if (SUB[i] == NULL) 
     return; 
} 


matvectmult_(M,M,P,h,Ph);     

hPh = vectordot_(M,h,Ph);     

inv = 1/(1+hPh); inv1 =&inv; 

scalarmult_(M,inv1,Ph,invPh);    

vectmatmult_(M,N,theta,h,hTtheta);   

vectorsub_(N,y,hTtheta,ymhTtheta);   

vectvectmult_(M,N,invPh,ymhTtheta,*ADD);  

vectvectmult_(M,M,invPh,h,*invPhhT);  

matmulc_(M,M,M,*invPhhT,P,*SUB);   

// Update theta 
matrixadd_(M,N,theta,*ADD,theta); 

// Update P 
matrixsub_(M,M,P,*SUB,P);    

free(Ph); 
free(invPh); 
free(hTtheta); 
free(ymhTtheta); 
for (i=0;i<*M;i++) 
    free(ADD[i]); 
free(ADD); 
for (i=0;i<*M;i++) 
    free(invPhhT[i]); 
free(invPhhT); 
for (i=0;i<*M;i++) 
    free(SUB[i]); 
free(SUB); 
} 
+1

我沒有看到任何MATLAB或MEX相關的東西,這是純粹的C ..也許你可以使用MEX API函數來分配像['mxMalloc'](http://www.mathworks.com/help/matlab/apiref /mxcalloc.html)(它在MEX函數退出時由MATLAB內存管理器自動釋放)。 – Amro

+0

爲什麼不使用'mxMalloc'和'mxFree'?你在使用「mex.h」嗎? – horchler

+0

因爲我不知道那些存在。使用mxMalloc而不是malloc有什麼好處? – user2480446

回答

0

這裏有一個問題 - 你有很多很多的return語句,你不以往任何一個調用釋放的內存。例如,如果invPh爲NULL,則爲Ph分配的內存將不會被釋放。

+0

總的來說很好,但是在這個特殊的代碼中,所有那些早期的'返回'只會在'malloc'失敗的情況下被觸發,在這種情況下,他已經用完了內存,所以它們不可能成爲泄漏。 –

0

考慮@Owen所說的話,我會將您的malloc語句放在只執行一次的do-while循環中,並用break代替所有return語句。

do { 
    // mxMalloc 
    if (someVar[i] == NULL) 
     break; 

    // etc... 
    // The real meat of your code inside the do-while loop 
} while 0 == 1; 
// mxFree functions out here 

我對編碼mex函數有點生疏。這樣做可能有更好的做法,但這可能會有所幫助。

您也可能需要檢查您嘗試釋放的每個變量是否也是!= NULL,儘管free函數可能會自動執行此操作。

編輯:更改了上面的代碼。我認爲@horchler在評論中說得最好:你應該使用mxMallocmxFree而不是mallocfree

+0

這裏有個問題。 'free(NULL)'根據定義是無操作的,所以沒有理由去檢查它。但是,如果你使用這個do/while/break邏輯,在早期的'break'的情況下,任何未被分配的變量都會有未初始化的內容,所以你最終可能會調用'free()'在一個隨機指針上,這是一個未定義的行爲(即可能會損壞內存的錯誤)。這可能不是一個好方法,除非增加額外的警衛或初始化。將分配解除分配給一個單獨的功能可能是另一種選擇。 –