Ошибка «free (): неверный следующий размер (быстрый)» при попытке освободить память массива - PullRequest
2 голосов
/ 14 мая 2019

Я пишу один из вариантов сортировки слиянием. В своей задаче я использую два массива: ключи в массиве arr и значения в массиве brr. Ключи - целые числа, а значения - строки. Функция слияния получает эти два массива l, m и r в качестве левого, среднего и правого индексов.

void merge(int arr[], char** brr, int l, int m, int r)

Я рассчитываю размеры двух новых массивов, которые мне понадобятся:

int size1 = m-l+1;
int size2 = r-m;

Чтобы объединить массивы, я создаю два новых массива для ключей и строк, используя функцию malloc:

int* left = malloc(size1*sizeof(int));
int* right = malloc(size2*sizeof(int));
char** lefts = malloc(size1*sizeof(char*));
char** rights = malloc(size2*sizeof(char*));

Затем я копирую значения из входных массивов:

for(int i = 0; i < size1; i++){
    left[i] = arr[l+i];
    lefts[i] = brr[l+i];
}

И выполнять сортировку по новым массивам.

i = j = 0;
k = l;
while(i < size1 && j < size2){
    if(left[i] < right[j]){
        brr[k] = lefts[i];
        arr[k] = left[i];
        i++;
    }else{
        brr[k] = rights[j];
        arr[k] = right[j];
        j++;
    }
    k++;
}

Затем я добавляю к brr массивам последние элементы и после попытки освободить память из rights массива я получаю ошибку.

free(lefts);
lefts = NULL;
free(rights);
rights = NULL;

Примечание: при попытке освободить память из массива lefts ошибки нет, только rights. Я пытался поменять местами free(lefts) и free(rights), но результат тот же.

Полный код функции:

void merge(int arr[], char** brr, int l, int m, int r){
    int size1 = m-l+1;
    int size2 = r-m;
    int* left = malloc(size1*sizeof(int));
    int* right = malloc(size2*sizeof(int));
    char** lefts = malloc(size1*sizeof(char*));
    char** rights = malloc(size2*sizeof(char*));

    for(int i = 0; i < size1; i++){
        left[i] = arr[l+i];
        lefts[i] = brr[l+i];
    }
    for(int i = 0; i < size2; i++){
        right[i] = arr[m+1+i];
        rights[i] = brr[m+1+i];
    }
    int i, j, k;
    i = j = 0;
    k = l;
    while(i < size1 && j < size2){
        if(left[i] < right[j]){
            brr[k] = lefts[i];
            arr[k] = left[i];
            i++;
        }else{
            brr[k] = rights[j];
            arr[k] = right[j];
            j++;
        }
        k++;
    }
    while(i < size1){
        brr[k] = lefts[i];
        arr[k] = left[i];
        k++;
        i++;
    }
    while(j < size2){
        brr[k] = rights[j];
        arr[k] = right[j];
        k++;
        j++;
    }
    free(left);
    left = NULL;
    free(right);
    right = NULL;
    free(lefts);
    lefts = NULL;
    free(rights);
    rights = NULL;
}

Функция MergeSort:

void mergeSort(int arr[], char** brr, int l, int r){
    if(l < r){
        int m = l+(r-l)/2;
        mergeSort(arr, brr, l, m);
        mergeSort(arr, brr, m+1, r);
        merge(arr, brr, l, m, r);
    }
}

Main:

int main(){
    const int maxStrings = 14;
    const int maxStringSize = 70;
    int n;

    scanf("%d", &n);
    getchar();

    int *Keys = malloc(n*sizeof(int));
    for(int i = 0; i < maxStrings; i++) Keys[i] = i;

    char **Strings = malloc(n*sizeof(char*));
    char *temp;
    for(int i = 0; i < n; i++){
        getStr(&temp, maxStringSize);
        Strings[i] = temp;
    }
    mergeSort(Keys, Strings, 0, n-1);
}

getStr:

void getStr(char **a, int n){
    *a = malloc(n*sizeof(char));
    char c;
    int i = 0;
    while( (c = getchar()) != '\n' && i < n-1){
        if(c == EOF){
            (*a)[i] = '\0';
            return;
        }
        (*a)[i++] = c;
    }
    (*a)[i] = '\0';
}

Ответы [ 2 ]

4 голосов
/ 14 мая 2019

Ошибка обычно является признаком перезаписи некоторой памяти, которая не принадлежит вам.Обычно вы уничтожаете «данные учета malloc» для переменной, которую вы освобождаете.

Так что ищите недопустимые записи в память.Как насчет этого кода?

int *Keys = malloc(n*sizeof(int));
for(int i = 0; i < maxStrings; i++) Keys[i] = i;

Вы malloc только n элементов, но все же вы пишете maxStrings элементов.Поэтому, если n меньше maxStrings, у вас есть выделенная память на стороне записи.

2 голосов
/ 14 мая 2019

В вашем основном это: for(int i = 0; i < maxStrings; i++) должно быть до n, а не до maxStrings нет?

...