【问题标题】:realloc(): invalid next size error in C programrealloc():C 程序中的下一个大小错误无效
【发布时间】:2019-07-24 19:16:06
【问题描述】:

我正在编写一个程序,它从输入文件中读取一组员工记录,并使用插入排序和快速排序分别对它们进行排序。它还找出不同数组大小的两种排序所花费的时间。我应该找到快速排序比插入排序更快的估计截止大小。为此,我编写了函数 estimateCutoff() ,该函数又调用 testRun()...(testRun() 找到对特定数组进行排序所需的时间,而 estimateCutoff() 比较这两次)。但是,每次程序运行时我都会遇到一个特定的错误:

realloc(): invalid next size
Aborted (core dumped)

在调试代码时,我发现错误发生在 testRun() 中分配数组 emp2 的过程中,该错误已被estimateCutoff() 作为返回调用。

realloc():下一个大小无效
程序收到信号 SIGABRT,已中止。 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51 51 ../sysdeps/unix/sysv/linux/raise.c: 没有这样的文件或目录。

谁能告诉我哪里出错了。

int estimateCutoff(empl * emp,int size){
    int min=0,max=size,mid;
    mid=(min+max)/2;
    time t=testRun(emp,mid);

    do
    {
        if(t.IStime<t.QStime)
            min=mid;
        else if(t.IStime>t.QStime)
            max=mid;
        else if(t.IStime==t.QStime)
            return mid;
        mid=(min+max)/2;
        t=testRun(emp,mid);
    } while(mid!=min && mid!= max);

    return mid;
}

这是testRun() 函数:

time testRun(empl * emp,int size){
    int i;
    empl *emp1=malloc(sizeof(empl)*size);
    for(i=0;i<size;i++)
    {
        emp1[i]=emp[i];
    }

    time t;
    struct timeval t1,t2,t3,t4;
    double elapsedTime1,elapsedTime2;

    gettimeofday(&t1,NULL);
    iter_insertionsort(emp1,size);
    gettimeofday(&t2,NULL);
    elapsedTime1=(t2.tv_sec-t1.tv_sec)*1000.0;
    elapsedTime1+=(t2.tv_usec-t1.tv_usec)/1000.0;
    t.IStime=elapsedTime1;

    empl *emp2=malloc(sizeof(empl)*size);
    for(i=0;i<size;i++)
    {
        emp2[i]=emp[i];
    }

    gettimeofday(&t3,NULL);
    itr_quicksort(emp2,size,1);
    gettimeofday(&t4,NULL);
    elapsedTime2=(t4.tv_sec-t3.tv_sec)*1000.0;
    elapsedTime2+=(t4.tv_usec-t3.tv_usec)/1000.0;
    t.QStime=elapsedTime2;

    return t;
}

main() 函数如下:

#include<stack.h>
#include<quick.h>
int main(){

    int arraycapacity=10;
    empl * emp=malloc(sizeof(empl)*arraycapacity);
    FILE * ptr=fopen("1000","r");
    int size=0;
    while(!feof(ptr))
    {
        fscanf(ptr,"%[^ ] %d\n",emp[size].name,&(emp[size].empID));
        size++;
        if(size==arraycapacity)
        {
            arraycapacity=arraycapacity*2;
            emp=realloc(emp,sizeof(empl)*arraycapacity);
        }
    }
    int mid=estimateCutoff(emp,size);
    printf("mid = %d\n",mid);
    fclose(ptr);
}

【问题讨论】:

  • 该消息意味着您已经超出了一块已分配内存的范围,并且损坏了内存管理代码使用的控制信息。如果可能,请获取Valgrind 并使用它来诊断问题。如果做不到这一点,请找出你踩踏出界的地方。
  • 那我会用 Valgrind 看看能不能用。
  • 感谢您提供的信息顺便说一句!
  • @JonathanLeffler valgrind 给出以下错误:VALGRIND INTERNAL ERROR: Valgrind received a signal 11 (SIGSEGV) - exiting --10016-- si_code=1;故障地址:0x790523C492; sp:0x1002ca9e30 valgrind:“不可能”发生:被致命信号杀死

标签: c


【解决方案1】:

main 中,您将每次测试的数组大小加倍,但从不检查realloc 是否成功。

您在每次调用testRun 时都调用了两次malloc,这发生在estimateCutoff 的循环内部,但您从未在任何内存中使用free,也从未检查malloc 是否成功。

这一切都是灾难的根源。您应该采取以下步骤:

  • 检查所有内存分配和重新分配是否成功。
  • free()testrun 中每个测试结束时的内存分配。
  • arraycapacity 设置限制
  • main中错误使用feof()的控制回路更改为


while(fscanf(ptr, "%[^ ] %d\n", emp[size].name, &(emp[size].empID)) == 2)
{
    // ...
}

因为scanf 系列返回成功扫描的项目数。

【讨论】:

  • 我按照你说的做了,但是,经过几次迭代,程序仍然报错:Continuing。损坏的大小与 prev_size 程序收到信号 SIGABRT,中止。 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51 51 ../sysdeps/unix/sysv/linux/raise.c:没有这样的文件或目录。
  • 可能排序功能有问题。
  • 排序功能运行良好,testRun() 也独立运行。只有当我使用estimateCutoff() 时才会发生错误。
  • 假设else if(t.IStime==t.QStime) 永远不会是真的?它们是浮点值。无论如何,您已经测试了 &lt;&gt; 那么为什么要使用 else 和不必要的测试?
猜你喜欢
  • 1970-01-01
  • 2015-04-12
  • 2014-10-13
  • 2016-01-02
  • 2020-12-27
  • 2018-06-13
  • 1970-01-01
相关资源
最近更新 更多