malloc:释放对象的校验和不正确

问题描述

下面是执行合并排序的功能。但执行时遇到错误。每次在功能merge中都释放了分配的内存(aux),为什么释放后会对其进行修改

a.out(65287,0x1112bedc0) malloc: Incorrect checksum for freed object
0x7ff9a4c05888: probably modified after being freed. Corrupt value:
0xb00000003 a.out(65287,0x1112bedc0) malloc: *** set a breakpoint in
malloc_error_break to debug Abort trap: 6
void merge(int arr[],int lo,int mid,int hi) {
    int i = lo; 
    int j = mid + 1;
    int *aux = (int *)malloc((hi - lo + 1) * sizeof(int));
    for (int k = lo; k <= hi; k++) {
        aux[k] = arr[k];
    }   
    for (int k = lo; k <= hi; k++) {
        if (i > mid)
            arr[k] = aux[j++];
        else if (j > hi)
            arr[k] = aux[i++];
        else if (aux[i] > aux[j])
            arr[k] = aux[j++];
        else
            arr[k] = aux[i++];
    } 
    free(aux);
}

void mergesort1(int arr[],int hi) {
    if (lo >= hi)
        return;
    int mid = lo + (hi - lo) / 2;
    mergesort1(arr,lo,mid);
    mergesort1(arr,mid + 1,hi);
    merge(arr,mid,hi);
}

致电:

mergesort1(arr,9);

解决方法

malloc((hi - lo + 1) * sizeof(int))为索引从0到hi-lo的元素分配空间,但是for (int k = lo; k <= hi; k++) … aux[k] = …访问索引从lohi的元素,因此在分配的内存。

,

aux数组未正确初始化:for (int k = lo; k <= hi; k++) { aux[k] = arr[k]; }应该为:

    for (int k = lo; k <= hi; k++) {
        aux[k -lo] = arr[k];
    }

您的代码写的操作超出了分配的数组的末尾,可能导致malloc()free()用来跟踪分配的内存的数据损坏。

请注意,ij的初始化方式也应不同,并且在合并排序算法中包含上限会造成混淆。如果排除hi,则代码会更简单,因为无需进行+1 / -1调整:

void merge1(int arr[],int lo,int mid,int hi) {
    int i = 0; 
    int j = mid -= lo;
    int n = hi - lo;
    int *aux = (int *)malloc(n * sizeof(int));
    for (int k = 0; k < n; k++) {
        aux[k] = arr[lo + k];
    }   
    for (int k = lo; k < hi; k++) {
        if (i >= mid)
            arr[k] = aux[j++];
        else if (j >= n)
            arr[k] = aux[i++];
        else if (aux[i] > aux[j])
            arr[k] = aux[j++];
        else
            arr[k] = aux[i++];
    } 
    free(aux);
}

void mergesort1(int arr[],int hi) {
    if (hi - lo < 2)
        return;
    int mid = lo + (hi - lo) / 2;
    mergesort1(arr,lo,mid);
    mergesort1(arr,mid,hi);
    merge1(arr,hi);
}

使用mergesort1(arr,10);进行调用,这更简单,因为数组长度为10。

可以使用指针算法进一步简化代码:

void merge2(int arr[],int hi) {
    int *aux = malloc(n * sizeof(*aux));
    for (int i = 0; i < n; i++) {
        aux[i] = arr[i];
    }   
    for (int i = 0,j = mid,k = 0; i < mid;) {
        if (j >= n || aux[i] <= aux[j])
            arr[k++] = aux[i++];
        else
            arr[k++] = aux[j++];
    } 
    free(aux);
}

void mergesort2(int arr[],int n) {
    if (n < 2)
        return;
    int mid = n / 2;
    mergesort2(arr,mid);
    mergesort2(arr + mid,n - mid);
    merge2(arr,n);
}

呼叫:mergesort2(arr,10);,其中10是数组长度。