【问题标题】:"free(): invalid next size (fast)" error when trying to free memory of array尝试释放数组内存时出现“free(): invalid next size (fast)”错误
【发布时间】:2019-05-14 18:42:53
【问题描述】:

我正在编写一种合并排序变体。在我的任务中,我使用了两个数组:arr 数组中的键和brr 数组中的值。键是整数,值是字符串。合并函数接收lmr这两个数组作为左、中、右索引。

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;
}

合并排序函数:

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);
    }
}

主要:

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';
}

【问题讨论】:

  • 您向我们展示了正确的代码。现在您需要做的就是向我们展示有错误的代码。见minimal reproducible example。顺便说一句,最好将代码拆分为单独的 sn-ps。只需一个可以复制/粘贴的代码块,就可以让他人更轻松地尝试您的代码。
  • @CacahueteFrito 如果大小可能很大,“使用实际数组”不是一个好主意
  • 完整的功能代码有可能是正确的。这一切都取决于传递给它的参数。
  • 可以删除末尾的那些NULL 分配。这些是局部变量,会消失
  • 好吧,似乎很难获得完整的代码......现在我们没有getStr。无论如何 - 我 99.99% 确信您会覆盖一些动态分配的内存,从而破坏 rights 的“分配簿记” BTW:请参阅 meta.stackoverflow.com/questions/254782/… 以获取可能的答案列表

标签: c malloc free


【解决方案1】:

该错误通常表示覆盖了一些不属于您的内存。通常,您已经为要释放的变量销毁了“mallocs 簿记数据”。

所以寻找非法的内存写入。这段代码怎么样?

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

mallocn 元素,但您仍然编写 maxStrings 元素。因此,如果n 小于maxStrings,则您有一个写出侧分配的内存。

【讨论】:

  • ty,现在它正在工作,但为什么错误只出现在 rights 数组?
  • @MaximCheremisinov 可能是因为非法写入只破坏了rights 的簿记,而其他变量没有被触及
【解决方案2】:

在您的主目录中,这:for(int i = 0; i &lt; maxStrings; i++) 应该最多 n,而不是最多 maxStrings 否?

【讨论】:

    猜你喜欢
    • 2013-04-20
    • 2011-01-19
    • 1970-01-01
    • 1970-01-01
    • 2016-05-08
    • 1970-01-01
    • 2015-07-13
    • 2015-01-13
    • 1970-01-01
    相关资源
    最近更新 更多