【问题标题】:incorrect checksum for freed object on large input大输入上释放对象的校验和不正确
【发布时间】:2026-01-20 18:45:01
【问题描述】:

我编写了一个程序,它计算 .txt 文件中的反转次数(第一个数字 - 数字的数量,而不是数字本身)。在小输入(5 或 10 个数字)上它工作正常,但是当输入是 100,000 个数字(并且每个数字小于 100,000)时,我收到以下错误:

incorrect checksum for freed object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug***

代码如下:

#include <stdio.h>

long int merge(int *arr, const int start, const int half, const int end)
{
        int s=start;
        int i=0;
        int cinv=0;
        int j=half+1;
        int* barr = new int[end+start-1];

        while((s<=half)&&(j<=end)){
                if(arr[s]<=arr[j]){
                        barr[i]=arr[s];
                        s++;

                }
                else{
                        barr[i]=arr[j];
                        j++;
                        cinv++;
                }
                i++;
        }

        if(s>half){
                for(int k = j;k<=end;k++){
                        barr[i]=arr[k];
                        i++;
                }
        }
        else{
                for(int k=s;k<=half;k++){
                        barr[i]=arr[k];
                        i++;
                }
        }

        for(int k=0;k<=end-start;k++) {
                arr[k+start]=barr[k];
        }
        delete[] barr;
        return cinv;
}

long int mergesort(int* arr, int start, int end){
    int half=(start+end)/2;
    long int cinv=0;

    if (start<end){
        cinv+=mergesort(arr, start, half);
        cinv+=mergesort(arr, half+1, end);
        cinv+=merge(arr, start, half, end);
        return cinv;
    }

    return cinv;
}

int main(){
    int len;
    freopen("input.txt", "rt", stdin);
    freopen("output.txt", "wt", stdout);
    scanf("%d", &len);
    int *arr= new int[len];

    for (int i=0; i<len; i++){
        scanf("%d", &arr[i]);
    }

    long int cinv=mergesort(arr, 0, len-1);

    printf("\nInversions with merge=%ld", cinv);

    delete [] arr;
    return 0;
}

提前感谢您的帮助。

【问题讨论】:

  • 也许添加'c'标签也是合适的,因为这段代码绝对不是C++,而是C。
  • main() 中数组barr 的意义何在?你初始化它,给它分配整数,然后再也不用它做任何事情。
  • 辅助数组barrinmerge中的维度应该是end - start + 1
  • @Arcoth int *arr= new int[len]; 不是 C.
  • 内存损坏,申请valgrind

标签: c++ c algorithm malloc


【解决方案1】:

merge 中的临时数组的维度,

int* barr = new int[end+start-1];

不正确。当您使用start == 0end == 1 调用merge 时,这将产生一个数组维度为0。在数组的另一端,它将分配两倍于所需的内存。将其更改为:

int* barr = new int[end - start + 1];

分配零字节的作用是实现定义的。即使输入数组很小,您的程序也会在我的 Linux 平台上可靠地崩溃。

【讨论】: