【问题标题】:getting an error while trying to free malloc尝试释放 malloc 时出错
【发布时间】:2020-04-02 15:29:03
【问题描述】:

所以我在学校的任务是编写一个函数,该函数获取一个 int size 参数、一个整数数组和一个 int flag,并返回一个指针数组,其中包含指向原始单元格的指针以排序方式排列的 int 数组(如果 flag==1,则升序,否则降序)。

我基本上是根据归并排序原则编写的,但由于某种原因,当程序尝试执行第 123 行时,我得到了一个 runtime error(释放一个临时 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);
}

【问题讨论】:

    标签: c arrays sorting


    【解决方案1】:

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

    第一个循环迭代end - start + 1 次,可能会在切片末尾访问arr。

    循环一直持续到p &gt;= mid 和q &gt;= end,写入tempArr[k],k 大于或等于分配给malloc() 的元素数。

    逻辑有缺陷:您比较 arr 在偏移量 p 和 q 处的元素,而不是通过数组 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");
    

    【讨论】:

      【解决方案2】:

      所以你应该使用:

      int main(void)
      

      在这个while q 永远不会更新所以我猜是无限循环?

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

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

      【讨论】:

      • 嘿,所以我尝试添加这些行 ``` for (i =start;i
      猜你喜欢
      • 2017-02-25
      • 2015-07-13
      • 2016-05-08
      • 1970-01-01
      • 2012-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多