尝试释放malloc时出现错误

时间:2020-04-02 15:29:03

标签: c arrays sorting

因此,我从学校受命编写一个函数,该函数获取一个int size参数,一个整数数组和一个int flag,并返回一个指针数组,该指针数组保存指向该指针的指针。原始int数组的单元格以排序方式(如果flag == 1则升序,否则降序)。

我基本上是根据合并排序的原则编写的,但是由于某种原因,我得到了runtime error,该错误在程序尝试执行第123行(释放temp int **数组)时发生 知道为什么会发生以及它是否可修复吗?

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>

#define SIZE 100

int **pointerSort(int *arr, unsigned int size, int ascend_flag);
void ptrMerge(int arr[], int start, int mid, int end, int *ptrArr[], int flag);
void pmergeSort(int arr[], int start, int end, int *ptrArr[], int flag);

void main() {
    unsigned int size, i;
    int arr[SIZE];
    int **pointers;
    int ascend_flag;

    printf("Please enter the number of items:\n");
    scanf("%u", &size);

    for (i = 0; i < size; i++)
        scanf("%d", &arr[i]);

    scanf("%d", &ascend_flag);

    pointers = pointerSort(arr, size, ascend_flag);

    printf("The sorted array:\n"); //Print the sorted array

    //printPointers(pointers, size);
    for (i = 0; i < size; i++)
        printf("d%\t%d", *pointers[i], pointers[i]);

    free(pointers);
}

int **pointerSort(int *arr, unsigned int size, int ascend_flag) {
    int **sortedArr;

    sortedArr = (int**)malloc(size * sizeof(int*));
    pmergeSort(arr, 0, size - 1, sortedArr, ascend_flag);

    return sortedArr;
}

void pmergeSort(int arr[], int start, int end, int *ptrArr[], int flag) {

    if (start < end) {
        int mid = (start + end) / 2;

        pmergeSort(arr, start, mid, ptrArr, flag);
        pmergeSort(arr, mid + 1, end, ptrArr, flag);

        ptrMerge(arr, start, mid, end, ptrArr, flag);
    }
}

void ptrMerge(int arr[], int start, int mid, int end, int *ptrArr[], int flag) {
    int i, k = 0;
    int p = start, q = mid + 1;
    int **tempArr;

    tempArr = (int**)malloc((end - start + 1) * sizeof(int*));

    for (i = start; i <= end; i++) {
        if (arr[p] < arr[q]) {
            tempArr[k] = &arr[p];
            k++;
            p++;
        } else { //(arr[p] > arr[q])
            tempArr[k] = &arr[q];
            k++;
            q++;
        }
    }
    while (p <= mid) {
        tempArr[k] = &arr[p];
        k++;
        p++;
    }
    while (q <= end) {
        tempArr[k] = &arr[q];
        k++;
        p++;
    }

    if (flag == 1) { 
        for (i = 0; i < k; i++) 
            ptrArr[start] = tempArr[i];
            start++;
        }
    } else {
        for (i = k - 1; i >= start; i--) {
            ptrArr[start] = tempArr[i];
            start++;
        }
    }

    for (i = 0; i < k; i++)
        printf("%x\t%d\n", ptrArr[i], *ptrArr[i]);
    printf("\n");

    free(tempArr);
}

2 个答案:

答案 0 :(得分:1)

您会遇到分段错误,因为ptrMerge函数通过写入tempArr分配数组的末尾破坏了内存。

第一个循环迭代end - start + 1次,有可能访问切片末尾之外的arr

循环持续到p >= midq >= end,并以大于等于tempArr[k]分配的元素数的k写入malloc()。 >

逻辑有缺陷:您将arr的元素在偏移量pq处进行比较,而不是通过数组ptrArr进行间接访问。

这是修改后的版本:

int **pointerSort(int *arr, int size, int ascend_flag) {
    int **sortedArr = (int**)malloc(size * sizeof(int*));
    for (int i = 0; i < size; i++) {
        sortedArr[i] = &arr[i];
    }
    pmergeSort(sortedArr, 0, size - 1, ascend_flag);
    return sortedArr;
}

void pmergeSort(int *ptrArr[], int start, int end, int flag) {
    if (start < end) {
        int mid = start + (end - start) / 2;
        pmergeSort(ptrArr, start, mid, flag);
        pmergeSort(ptrArr, mid + 1, end, flag);
        ptrMerge(ptrArr, start, mid, end, flag);
    }
}

void ptrMerge(int *ptrArr[], int start, int mid, int end, int flag) {
    int i, k, n = end - start + 1;
    int p = start, q = mid + 1;
    int **tempArr = (int**)malloc(n * sizeof(int*));

    for (k = 0; k < n; k++) {
        if (p <= mid && (q >= end || *ptrArr[p] <= *ptrArr[q])) {
            tempArr[k] = ptrArr[p++];
        } else {
            tempArr[k] = ptrArr[q++];
        }
    }
    if (flag == 1) { 
        for (k = 0; k < n; k++) 
            ptrArr[start + k] = tempArr[k];
        }
    } else {
        for (k = 0; k < n; k++) {
            ptrArr[end - k] = tempArr[k];
        }
    }
    free(tempArr);
}

还请注意,main()必须使用返回类型int进行定义,并且打印值的循环会中断。它应显示为:

    for (i = 0; i < size; i++)
        printf("%d\t", *pointers[i]);
    printf("\n");

答案 1 :(得分:0)

因此,您应该使用:

int main(void)

在此期间,q从未更新,所以我猜无限循环吗?

while (q <= end)
    {
        tempArr[k] = &arr[q];
        k++;
        p++;
    }

您能为我提供您想要的输入和输出吗? 我已经尝试过您的代码,但没有收到错误消息。