C、为什么我的自定义自由函数给我 "pointer being freed was not allocated" 错误

C, Why does my custom free function give me the "pointer being freed was not allocated" error

我正在尝试动态分配一个数组,将一些数据放入其中,然后释放它并将数组指针设置为空,以便以后无法访问它。此外,不相关,但我将数组的大小存储在第一个元素中,然后将其返回索引一个向上,它是赋值的一部分,所以希望这不会混淆任何人。

如果我对错误的理解是正确的,我会尝试在我的 malloc 数组被复制到的数组上调用 free()。这是不允许的,因为 free() 不是在实际的 malloc 数组上调用,而是在保存其值的数组上调用。

如果是这种情况,我将如何修复我对 free() 的调用以仅接收一个数组地址并像 free(*array); 那样取消引用它。现在我有一些乱七八糟的星号和演员阵容,我不知道为什么会这样。如果您知道如何解决上面的免费电话问题,或者只是解释为什么我现在的方法有效,我将不胜感激。我的目标是能够将自定义自由函数的参数设置为空指针而不是特定数据类型指针。谢谢!!

#include <stdlib.h>

int getSizeArray(void *array);
void * createArray(int n, int sizeOfDatatype);
void freeArray(double ** array);


int main(void){

    double * arr = createArray(10, sizeof(double));
    int size = getSizeArray(arr);

    /* using output for error checking
    for(int i = 0; i < 10; i++){
        arr[i] = i;
    }

    for(int j = 0; j < 10; j++){
        printf("%f\n", arr[j]);
    }
    */

    void* p = &arr;

    freeArray(p);

}


int getSizeArray(void *array){
    int s = ((int *) array)[-1];
    return s;
}


void * createArray(int n, int sizeOfDatatype){
    int * array = malloc((n * sizeOfDatatype) + sizeof(int));
    array[0] = n;
    return (void*) (array + 1);
}


void freeArray(double ** array){
    free(*array);
    *array = NULL;
}

编辑:查看@JonathanLeffler 评论。问题在于对齐。我切换了我的一些代码,但我不得不索引一个而不是在我的函数中,而是在 main

#include <stdlib.h>

int getSizeArray(void *array);
void * createArray(int n, int sizeOfDatatype);
void freeArray(double ** array);


int main(void){

    double * arr = createArray(10, sizeof(double));
    arr = (void*) (arr + 1);
    int size = getSizeArray(arr);

    /* using output for error checking*/
    for(int i = 0; i < 10; i++){
        arr[i] = i;
    }

    for(int j = 0; j < 10; j++){
        printf("%f\n", arr[j]);
    }

    arr = (double*) (arr - 1);

    freeArray(&arr);

    for(int j = 0; j < 10; j++){
        printf("%f\n", arr[j]);
    }

}


int getSizeArray(void *array){
    int s = ((int *) array)[-1];
    return s;
}


void * createArray(int n, int sizeOfDatatype){
    int * array = malloc((n * sizeOfDatatype) + sizeof(int));
    array[0] = n;
    return array;
}


void freeArray(double ** array){
    free(*array);
    *array = NULL;
}

如果你free(*array),之后就不需要*array = NULL了。

此外,您不能将 (void *) 投射到 (int *) 上并将其分配给 (double *)

最后,如果 p 是单指针,你不能 freeArray(p); 因为 freeArray(double ** array) 有一个参数 double 双指针。

希望这对您有所帮助。

大家可以对比一下我修改后的代码

#include <stdlib.h>
#include <stdio.h>

int getSizeArray(void *array);
void * createArray(int n, int sizeOfDatatype);
void freeArray(void ** array);


int main(void){

    double * arr = (double *)createArray(10, sizeof(double));
    int size = getSizeArray(arr);

    printf("size of arr %d\n", size);

    // using output for error checking
    for(int i = 0; i < 10; i++){
        arr[i] = i;
    }

    for(int j = 0; j < 10; j++){
        printf("%f\n", arr[j]);
    }


    void ** p = (void **)&arr;

    freeArray(p);
    printf("del arr, then arr = %u\n",(unsigned)arr);

}


int getSizeArray(void *array){
    int s = ((int *) array)[-1];
    return s;
}


void * createArray(int n, int sizeOfDatatype){
    int * array = (int*)malloc((n * sizeOfDatatype) + sizeof(int));
    array[0] = n;
    return (void*) (array + 1);
}


void freeArray(void ** array){
    free(((int*)*array)-1);
    *array = NULL;
}


输出:

size of arr 10
0.000000
1.000000
2.000000
3.000000
4.000000
5.000000
6.000000
7.000000
8.000000
9.000000
del arr, then arr = 0

我为另一个用户提供了这个问题的。必须是 class 赋值。除了我使用宏而不是函数外,我的版本与您的非常相似。无论如何,@Serge 的回答非常接近。它是 -1 而不是 +1。

这是我插入我的代码的东西,它运行良好:

void freeArray(void** array)
{
    free( ((int*)(*array)) - 1 );
    *array = NULL;
}

让我解释一下发生了什么。 C 分配例程基本上就是在做您正在做的事情。他们将数组大小保存在实际数组之上一个字。关注 link 以获取有关 free() 工作原理的更多信息。在我们的版本中,我们将数组大小保存为比实际数组高一个 int(2 words/4 字节)。您的代码错误,因为您引用的地址是第三个元素而不是第一个。您需要传入数组分配的起始地址,即 ((int*)(*array)) - 1.