2014-05-21 30 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