2014-05-21 33 views
0

所以,我在做這個練習:realloc()浪費了一大堆空間,我做錯了什麼?

編寫一個C語言函數void出現(字符* S,焦炭C,焦*** OCCP, INT * N),給定一個字符串s和一個char C,計數的 出現在字符串s炭數c,返回OCCP炭的新數組,它包含每個C 發生s中不會忽略的ADRESS中n表示數,並返回在

主要樣品:

#include <stdio.h> 

int main(){ 
    int i, n; 
    char** occ; 
    occorrenze("engineering", 'n', &occ, &n); 
    for (i=0; i<n; ++i) printf("%s\n", occ[i]); // prints ngineering neering ng 
    free(occ); 
} 

最初我寫的功能是這樣的:

void occurrences(char* s1, char c, char*** s, int* n){ 
    *n=0; 
    char* arr[2]; 
    int length=strlen(s1); 
    int i; 
    for(i=0; i<length; i++){ 
     if(s1[i]==c)(*n)++; 
    } 
    *s=(malloc((*n)*sizeof(char**))); 
    int a=0; 
    for(i=0; i<length; i++){ 
     if(s1[i]==c){ 
      (*s)[a]= &s1[i]; 
      a++; 
     } 
    } 
} 

效果不錯,但我想嘗試並重新寫迭代字符串只是一個時間。我想用的realloc()函數,我從來沒有使用過,最終我來到了這一點:

void occurrences(char* s1, char c, char*** s, int* n){ 
    *n=0; 
    *s=malloc(0); 
    char* arr[2]; 
    int length=strlen(s1); 
    int i,a=0; 
    for(i=0; i<length; i++){ 
     if(s1[i]==c){ 
      (*n)++; 
      *s=realloc(*s,(*n)*sizeof(char**)); 
      (*s)[a]= &s1[i]; 
      a++; 

     } 
    } 
} 

這一次似乎也很好的工作,但後來我跑Valgrind的:

==4893== HEAP SUMMARY: 
==4893==  in use at exit: 0 bytes in 0 blocks 
==4893== total heap usage: 4 allocs, 4 frees, 48 bytes allocated 
==4893== 
==4893== All heap blocks were freed -- no leaks are possible 
==4893== 
==4893== For counts of detected and suppressed errors, rerun with: -v 
==4893== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2) 

48字節分配?它應該是24個字節,對吧? 總堆大小爲8 * n!而不是8 * N個......我想我失去了一些東西XD

編輯:複製權函數笑

+0

爲什麼你認爲它應該是24? – nos

+0

@Andrew Medico複製/粘貼錯誤,很抱歉! – Atlas80b

+2

32位或64位系統? 64位系統使用8個字節的指針,這將使48個。 – DoxyLover

回答

0

堆使用:

如果malloc(1),系統分配的內存用於你,能夠保持一個字節塊。你可能沒有意識到,系統一般不會分配一個字節。實際上,分配的內存塊很可能大得多;也許最少8,16或32個字節。因此,malloc() ed space不等於heap space -used。

由於上述'最小'系統內存分配,函數realloc()可能會返回與給定的地址相同的地址;如果該地址的系統分配足夠大,以適應(在你的情況下)更大的尺寸。一旦系統分配變得太小,realloc()將返回一個新的地址到更大的系統內存塊(很可能比realloc要求的大)。


幾點意見:

void occurrences(char* s1, char c, char*** s, int* n){ 
    *n=0; 
    *s=NULL; 

改變上述行。不需要malloc(0);。的sNULL)的值將在以realloc(),然後工作就像malloc()傳遞,

char* arr[2]; 
    int length=strlen(s1); 
    int i,a=0; 
    for(i=0; i<length; i++){ 
    if(s1[i]==c){ 
     (*n)++; 
     *s=realloc(*s,(*n) * sizeof(char**)); // !DANGER! 

代替上述線,請看下面:

if(s1[i]==c){ 
     char *tmp; 
     (*n)++; 
     tmp=realloc(*s,(*n) * sizeof(char**)); // Much better. 
     if(NULL == tmp) 
      { 
      /* Handle realloc() failure. */ 
      ... 
      } 
     else 
      *s = tmp; 

     ... 

如果你不」 t如上所示,如果realloc()失敗,先前分配的內存(由s指向)將丟失;取而代之的是NULL

 (*s)[a]= &s1[i]; 
     a++; 

    } 
} 

}

+0

非常感謝您的建議^^ – Atlas80b

4

不Valgrind的衡量整個應用程序的執行總分配的內存?

0 + 8 + 16 + 24 = 48。

+0

我剛剛發現我誤解了valgrind的輸出結果。謝謝XD – Atlas80b