求助 C语言realloc和free触发断点的问题

Westlake96 2017-03-31 02:42:05
LZ目前自学C语言 在写小程序的时候遇到一些问题 请各位大牛赐教一下 非常感谢

关联问题1:realloc触发断点问题
描述:LZ想要通过realloc实现动态数组 结果发现程序运行在realloc的时候 经常会停掉 为此调试后发现 运行到realloc处会自动触发断点 然后程序就无法继续运行下去了 代码如下

#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;
}

问题截图如下




关联问题2:free释放触发断点问题
描述:LZ想要写个和realloc看起来差不多的功能出来 创建了一个函数 用于开辟一个新的堆空间 将原始堆空间的数据拷贝到新空间中 然后释放原始空间 结果发现 释放原始空间的时候 free会触发断点 代码如下

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

#pragma warning(disable:4996)

void myRealloc(int **buf, int oldsize, int newsize)
{
int *tmp = 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 = calloc(sizeof(int), bufSize);
int *count = 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;
myRealloc(&buf, bufSize, bufSize);
printf("%d\n", bufSize);
}
}
else
{
*(buf + index) = tmp;
*(count + index) += 1;
}
}

free(buf);
free(count);
puts("over");
return 0;
}

问题截图如下


请各位大牛解答一二 非常感谢!
...全文
882 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
欧阳春晖 2017-04-01
  • 打赏
  • 举报
回复
引用 1 楼 paschen 的回复:
估计使用堆内存越界导致堆破坏

一般在释放或重新分配时会导致崩溃

所以检查你代码有没越界等

如果是这样,楼主可以从网上下载完全也堆工具进行检测。
以下是参考资料和下载链接:
堆调试工具——pageheap的使用和原理分析
pageheap下载1
pageheap下载2
如有安全软件拦截,可放行。
赵4老师 2017-03-31
  • 打赏
  • 举报
回复
仅供参考:
//文件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;
}
自信男孩 2017-03-31
  • 打赏
  • 举报
回复
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;
}
自信男孩 2017-03-31
  • 打赏
  • 举报
回复
#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;
}
Westlake96 2017-03-31
  • 打赏
  • 举报
回复
引用 2 楼 ptrunner 的回复:
bufLen*1.5只分配了15Byte,而For循环中为10000,内存越界导致的。
buf是有变化的哦 buf *= 1.5 想的是每次分配空间不够用了 就分配一个比现在空间大1.5倍的空间存放数据
pstrunner 2017-03-31
  • 打赏
  • 举报
回复
bufLen*1.5只分配了15Byte,而For循环中为10000,内存越界导致的。
paschen 2017-03-31
  • 打赏
  • 举报
回复
估计使用堆内存越界导致堆破坏 一般在释放或重新分配时会导致崩溃 所以检查你代码有没越界等

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧