user-0 提问: 求助 C语言realloc和free触发断点的问题

回复:
user: user-1
content: 引用 1 楼 user-5 的回复:估计使用堆内存越界导致堆破坏  一般在释放或重新分配时会导致崩溃  所以检查你代码有没越界等 如果是这样，楼主可以从网上下载完全也堆工具进行检测。 以下是参考资料和下载链接： 堆调试工具——pageheap的使用和原理分析 pageheap下载1 pageheap下载2 如有安全软件拦截，可放行。

user: user-2
content: 仅供参考：//文件1中的内容排序并去重,结果保存到文件2中 #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAXCHARS 128      //能处理的最大行宽,包括行尾的\n和字符串尾的\0 int MAXLINES=10000,MAXLINES2; char *buf,*buf2; int c,n,hh,i,L; FILE *f; char ln[MAXCHARS]; int ignore_case=0; int icompare(const void *arg1,const void *arg2) {    return stricmp((char *)arg1,(char *)arg2); } int compare(const void *arg1,const void *arg2) {    return strcmp((char *)arg1,(char *)arg2); } int main(int argc,char **argv) {     if (argc<3) {         printf("Unique line. Designed by zhao4zhong1@163.com. 2012-08-20\n");         printf("Usage: %s src.txt uniqued.txt [-i]\n",argv[0]);         return 1;     }     if (argc>3) ignore_case=1;//若存在命令行参数3，忽略大小写     f=fopen(argv[1],"r");     if (NULL==f) {         printf("Can not find file %s!\n",argv[1]);         return 1;     }     buf=(char *)malloc(MAXLINES*MAXCHARS);     if (NULL==buf) {         fclose(f);         printf("Can not malloc(%d LINES*%d CHARS)!\n",MAXLINES,MAXCHARS);         return 2;     }     n=0;     hh=0;     i=0;     while (1) {         if (NULL==fgets(ln,MAXCHARS,f)) break;//         hh++;         L=strlen(ln)-1;         if ('\n'!=ln[L]) {//超长行忽略后面内容             printf("%s Line %d too long(>%d),spilth ignored.\n",argv[1],hh,MAXCHARS);             while (1) {                 c=fgetc(f);                 if ('\n'==c || EOF==c) break;//             }         }         while (1) {//去掉行尾的'\n'和空格             if ('\n'==ln[L] || ' '==ln[L]) {                 ln[L]=0;                 L--;                 if (L<0) break;//             } else break;//         }         if (L>=0) {             strcpy(buf+i,ln);i+=MAXCHARS;             n++;             if (n>=MAXLINES) {                 MAXLINES2=MAXLINES*2;                 if (MAXLINES2==1280000) MAXLINES2=2500000;                 buf2=(char *)realloc(buf,MAXLINES2*MAXCHARS);                 if (NULL==buf2) {                     printf("Can not malloc(%d LINES*%d CHARS)!\n",MAXLINES2,MAXCHARS);                     printf("WARNING: Lines >%d ignored.\n",MAXLINES);                     break;//                 }                 buf=buf2;                 MAXLINES=MAXLINES2;             }         }     }     fclose(f);     if (n>1) {         if (ignore_case) qsort(buf,n,MAXCHARS,icompare);         else qsort(buf,n,MAXCHARS,compare);     }     f=fopen(argv[2],"w");     if (NULL==f) {         free(buf);         printf("Can not create file %s!\n",argv[2]);         return 2;     }     fprintf(f,"%s\n",buf);     if (n>1) {         if (ignore_case) {             hh=0;             L=MAXCHARS;             for (i=1;i<n;i++) {                 if (stricmp((const char *)buf+hh,(const char *)buf+L)) {                     fprintf(f,"%s\n",buf+L);                 }                 hh=L;                 L+=MAXCHARS;             }         } else {             hh=0;             L=MAXCHARS;             for (i=1;i<n;i++) {                 if ( strcmp((const char *)buf+hh,(const char *)buf+L)) {                     fprintf(f,"%s\n",buf+L);                 }                 hh=L;                 L+=MAXCHARS;             }         }     }     fclose(f);     free(buf);     return 0; }

user: user-3
content: myRealloc(&buf, bufSize, bufSize);  myRealloc函数中后面的两个实参是一样的，大小一样，就没有old或者new，这样会导致myRealloc中的buf越界。  #include <stdio.h> #include <stdlib.h> #include <string.h>  #pragma warning(disable:4996)  void myRealloc(int **buf, int oldsize, int newsize) {     int *tmp = (int *)calloc(sizeof(int), newsize);     for (int i = 0; i < oldsize; i++)     {         *(tmp + i) = *(*buf + i);     }     free(*buf);     *buf = tmp; }  int main(void) {     FILE *fr = fopen("d:\\test.txt", "rb");     int bufSize = 10;     int bufIndex = 0;     int *buf = (int *)calloc(sizeof(int), bufSize);     int *count = (int *)calloc(sizeof(int), bufSize);      while (!feof(fr))     {         int tmp = 0;         fscanf(fr, "%d", &tmp);         int index = getBufIndex(buf, bufSize, tmp);         if (index == -1)         {             *(buf + bufIndex) = tmp;             *(count + bufIndex) += 1;             bufIndex++;             if (bufIndex == bufSize)             {                 //bufSize *= 1.5;   /*del */                 myRealloc(&buf, bufSize, bufSize * 1.5);    /*old and new*/                 printf("%d\n", bufSize);             }         }         else         {             *(buf + index) = tmp;             *(count + index) += 1;         }     }      free(buf);     free(count);     puts("over");     return 0; }

user: user-3
content: #include <stdio.h> #include <stdlib.h> #include <string.h>   #pragma warning(disable:4996)   int main(void) {     int bufLen = 10;     int *nums = calloc(sizeof(int), bufLen);     for (int i = 0; i < 10000; i++)     {         *(nums + i) = i;         if (i == bufLen - 1)         {             realloc(nums, bufLen * 1.5);             bufLen *= 1.5;             printf("%d\n", bufLen);         }     }     puts("--over--");     return 0; } 该程序已经越界，注意，第一次realloc是将nums的空间缩小了，原来是10 × 4 = 40, 现在的长度是10 × 1.5 = 15； 但是realloc申请的新空间没有给nums，所以nums的有效空间还是40（10个int），即使这样，还是越界，因为i的值在增加； 如果你的想法是递增的增加内存，详见下面的demo: #include <stdio.h> #include <stdlib.h> #include <string.h>  #pragma warning(disable:4996)  int main(void) {     int i;     int bufLen = 10;     //int *nums = calloc(sizeof(int), bufLen);     int *nums = (int *)calloc(bufLen , sizeof(int));      for (i = 0; i < 10000; i++) {         *(nums + i) = i;         printf("i = %d\n", i);         if (i == bufLen - 1) {             nums = (int *) realloc(nums, bufLen * sizeof(int) * 1.5);             if (!nums) {                 fprintf(stdout, "realloc error!\n");                 exit(-1);             }             bufLen *= 1.5;             printf("bufLen = %d\n", bufLen);         }     }     puts("--over--");     return 0; }

user: user-0
content: 引用 2 楼 ptrunner 的回复:bufLen*1.5只分配了15Byte，而For循环中为10000，内存越界导致的。 buf是有变化的哦  buf  *= 1.5 想的是每次分配空间不够用了 就分配一个比现在空间大1.5倍的空间存放数据

user: user-4
content: bufLen*1.5只分配了15Byte，而For循环中为10000，内存越界导致的。

user: user-5
content: 估计使用堆内存越界导致堆破坏  一般在释放或重新分配时会导致崩溃  所以检查你代码有没越界等