2015-12-24 27 views
0

我有一個c函數,它使用malloc產生我的一個int數組。它的工作非常安靜,我認爲它的作用並不重要,因爲問題實際上與此無關。 (在這種情況下,它計算給定的int和base的數字)。我需要這個數組臨時在一個函數,這可能是一個子函數的子函數...(你有這個想法,指出這個函數可以使用多次),並在返回之前,我想運行免費,但它不起作用。這裏是一個測試代碼(它使用qsort對它們的二進制表示中的整數進行排序(是的,我知道可以更直接地計算結果,但重點是我嘗試運行free時遇到的問題(在功能上的人在這裏註釋掉))):C:由malloc函數產生的自由臨時數組

#include <stdio.h> 
#include <stdlib.h> 

int values[] = { 88, 56, 100, 2, 25, 0, 15}; 
int * baseString(int u, int base); 
int abs(int a); 
int ones(int a); 

int cmpfunc (const void * a, const void * b) 
{ 
    return ones(*(int*)a)>ones(*(int*)b); 
} 

int main() 
{ 
    int n; 

    printf("Before sorting the list is: \n"); 
    for(n = 0 ; n < 7; n++) 
    { 
     printf("%d ", values[n]); 
    } 

    qsort(values, 7, sizeof(int), cmpfunc); 

    printf("\nAfter sorting the list is: \n"); 
    for(n = 0 ; n < 7; n++) 
    { 
     printf("%d (Ones=%d) ", values[n], ones(values[n])); 
    } 
    printf("\n"); 
    return(0); 
} 

int abs(int a){ 
    return (a<0)? a*-1:a; 
} 

int* baseString(int u, int base){ 
    int* r=malloc(sizeof(int)); 
    r[0]=base; 
    r[1]=1; 
    if(base<2){ 
     r[2]=-1; 
     return r; 
    } 
    int negativ=0; 
    if(u<0){ 
     u=abs(u); 
     negativ=1; 
    } 
    int i=2; 
    do{ 
     int ur=u%base; 
     r[i]=ur; 
     u/=base; 
     i++; 
    }while(u>0); 
    r[1]=i-1; 
    if(negativ){ 
     r[1]=-r[1]; 
    } 
    return r; 
} 

int ones(int a){ 
    int* ai=baseString(a, 2); 
    int a1=1; 
    for(int i=2; i<abs(ai[1]); i++){ 
     if(ai[i]==1){ 
      a1++; 
     } 
    } 
    if(!a){ 
     a1=0; 
    } 
    //free(ai); 
    return a1; 
} 

PS:我安靜肯定這個線程是胎面的一些重複的地方,但我沒有發現它。

+0

'abs'函數已經存在 BLUEPIXY

+2

'int * r = malloc(sizeof(int));''r'只有一個元素。 – BLUEPIXY

+0

它..「不起作用」? –

回答

1

這裏出現的關鍵問題是ABW(陣列邊界寫)。在baseString函數中,實際上分配的內存等於1個整數的大小,但試圖像r[1],r[2], r[i]等中的數組那樣訪問它,這會導致寫入技術上不屬於您的內存。

在你的代碼的代碼片斷對應於

int* r=malloc(sizeof(int)); 
r[0]=base; 
r[1]=1; //ABW here 
if(base<2){ 
    r[2]=-1; //ABW here 
    return r; 
} 

    do{ 
     int ur=u%base; 
     r[i]=ur; //ABW here 
     u/=base; 
     i++; 
    }while(u>0); 

這可能會在你的代碼的任何時間點會導致不確定的行爲。在你的情況下,它似乎正在影響free,因爲內存覆蓋可能與malloc的內部預訂數據和自由實現有關。

+0

關於它沒有「可能」。你指出的例子DO表現出未定義的行爲。未定義的行爲並不意味着崩潰。這意味着任何事情都可以發生 - 碰撞只是其中一種可能性。 – Peter

1

你問題的一部分其實很簡單。

在你baseString()功能時,第一三行是

int* r=malloc(sizeof(int)); 
r[0]=base; 
r[1]=1; 

malloc()動態分配單個int,或具有一個元素的數組。 r[1] = 1修改具有一個元素的數組的第二個元素。

結果是未定義的行爲。像這樣的數組末尾運行的一個常見症狀是破壞程序中的內存,例如malloc()free()內部用來跟蹤分配和釋放的內存。這將解釋你的問題。

確保您分配了所需元素的數量。例如,如果需要10個元素,則需要malloc(10*sizeof(int))。您需要計算出所需的數量,因爲動態數組不會奇蹟般地增長以獲取所需的元素數量。

我沒有看得更遠,所以可能還有其他問題。但是這個非常明顯。

檢查malloc()實際上是否成功也是一個好主意。如果失敗,則返回NULL

+0

好吧我需要至少3這將是malloc(int * 3),但我不知道有多大的數組將得到是malloc的整點(好吧,在這種情況下,它可能只有34(最大int int二進制),但如果我不知道這個,我該怎麼辦?)。那麼我的代碼的其餘部分是如何工作的? – user3284214

+0

'malloc()'(和運算符'new')的意義在於,(通常情況下)程序運行之前,所需的內存量是未知的。如果在程序運行之前已知內存量,則可以使用其他技術,編譯器可以處理初始化和釋放。 – Peter

+0

好吧,但這仍然意味着我將不得不知道我最終可能需要的最大內存量。如果我不這樣做?當然,我可以在一段時間內運行程序,並計算出我需要多少空間,但這不是很實際嗎? – user3284214