2016-01-13 89 views
2

我很想知道为什么realloc()不能在我的循环中工作。我做了一个grep函数,我在一个大的文本文件上测试,突然程序崩溃告诉我“堆的腐败”所以我决定打破它在小范围内尝试,但问题仍然存在。有人可以解释什么是错的?为什么realloc在这个while循环中不起作用?

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

void grep(const char *Pattern,FILE *file); 

int main(void) 
{ 
    FILE *file; 
    if(fopen_s(&file,"file.txt","r")) 
     return 1; 
    grep("word",file); 
    fclose(file); 
    return 0; 
} 

void grep(const char *Pattern,FILE *file) 
{ 
    size_t size = 5*sizeof(char); 
    char *_Buf = (char*)malloc(size); 
    int n = 0, c; 
    while(c=getc(file)) 
    { 
     _Buf[n++] = c; 
     if(c == '\n' || c == EOF) 
     { 
      _Buf[n] = '\0'; 
      if(strstr(_Buf,Pattern)) 
       printf("%s",_Buf); 
      if(c == EOF) 
       break; 
      n = 0; 
     } 
     if(n == size) 
     { 
      size += 5; 
      realloc(_Buf,size); 
     } 
    } 
    free(_Buf); 
} 
+0

您必须使用'_Buf = realloc(_Buf,size);' – Magix

+1

@BLUEPIXY是不是像成功返回0? –

+1

'_Buf [n ++] = c;'会将一个截断的'EOF'值作为字符串中的最后一个字符。假设'EOF'的'int'值为'-1',十六进制值为'0xFFFFFFFF'(32位'int'),它将截断为'char'值'0xFF',这将有效地打印为输出行末尾的空格。你不会看到它,但如果你保存你的输出到一个文件或用十六进制编辑器或类似的东西看它,你会想知道从哪里来。 –

回答

5

在指针上调用realloc()不会调整旧指针。它释放旧指针并返回一个包含新分配的新指针。之后您需要使用返回的指针。

C11标准,章§7.22.3.5,realloc功能

void *realloc(void *ptr, size_t size);

realloc功能将释放旧的对象通过ptr指向和 指针返回到一新的对象的尺寸由size指定。 [...]

因此,您需要收集返回的指针,检查NULL并将其指回给前一个指针,如同您所愿。

那就是说,please see this discussion on why not to cast the return value of malloc() and family in C.

+1

谢谢你的回答。我的错误是一个彻底的错误。至于没有施放'malloc'的结果我知道,我已经看到它就像上百万次,但是我使用C++编译器,所以这就是为什么我施放: ) –

+0

@ machine_1不客气。只是说,坚持一个C编译器来编译C代码。 –

4

你是不是assinging的realloc()返回指针变量/指针:

realloc(_Buf,size); 

用途:

char * _New_Buf = realloc(_Buf,size); 
if(_New_Buf != NULL) 
    _Buf = _NewBuf; 
else 
    ; // add some error handling here 

否则,free()也将是免费的,荷兰国际集团的错误的内存指向可能无效的_Buf

+0

请不要建议'_Buf = realloc(_Buf,size);',以防realloc失败.... –

+0

[请参阅此讨论,为什么不在''malloc()'和family中返回值' C'](http://stackoverflow.com/q/605845/2173917)。 –

+0

@SouravGhosh - 确实,更新了答案。 –

相关问题