简体   繁体   English

C、为什么我的自定义释放函数给我“被释放的指针未分配”错误

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

I am trying to dynamically allocate an array, put some data in it, and then free it and set the array pointer to null so that it can not be accessed in the future.我试图动态分配一个数组,在其中放入一些数据,然后释放它并将数组指针设置为空,以便将来无法访问它。 Also, unrelated, but I am storing the size of the array in the first element and then passing it back indexed one up, it is part of the assignment, so hopefully that doesn't confuse anyone.另外,不相关,但我将数组的大小存储在第一个元素中,然后将其传递回索引一个,这是分配的一部分,所以希望这不会混淆任何人。

If I am understanding the error correctly, I am trying to call free() on the array that my malloc'ed array was copied in to.如果我正确理解了错误,我会尝试在我的 malloc 数组被复制到的数组上调用free() This is not allowed because free() is not being called on the actual malloc'ed array but rather the one that's holding its values.这是不允许的,因为free()不是在实际的 malloc 数组上调用,而是在保存其值的数组上调用。

If this is the case, how would I fix my call of free() to only receive an array address and dereference it like free(*array);如果是这种情况,我将如何修复我对free()调用以仅接收一个数组地址并像free(*array);一样取消引用它free(*array); . . Right now I have some mess of asteriscs and a cast and I have no idea why it works.现在我有一些乱七八糟的星号和演员阵容,我不知道它为什么有效。 If you know how to fix the free call into the above or just explain why what I have now works, I would greatly appreciate it.如果您知道如何将免费电话修复为上述问题,或者只是解释我现在所做的工作的原因,我将不胜感激。 My goal is to be able to set the parameter for the custom free function to a void pointer instead of a specific data type pointer.我的目标是能够将自定义自由函数的参数设置为 void 指针而不是特定数据类型指针。 Thanks!!谢谢!!

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

EDIT: Look to @JonathanLeffler comment.编辑:看看@JonathanLeffler 的评论。 The issue is with alignment.问题在于对齐。 I switched around some of my code but I had to index back one and not cast in my functions but instead in main我切换了我的一些代码,但我不得不索引一个,而不是在我的函数中转换,而是在 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;
}

I provided a complete solution to this problem for another user.我为另一个用户提供了这个问题的完整解决方案 Must be a class assignment.必须是课堂作业。 My version is very similar to yours except I used macros instead of functions.我的版本与你的非常相似,只是我使用了宏而不是函数。 Anyway, @Serge answer was so close.无论如何,@Serge 的答案非常接近。 It -1 not +1.它-1而不是+1。

Here what I plug into my code and it worked fine:在这里,我插入我的代码并且运行良好:

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

Let me explain what going on.让我解释一下发生了什么。 The C allocation routines are basically doing what you are doing. C 分配例程基本上是在做你正在做的事情。 They save the array size one word above the actual array.他们将数组大小保存在实际数组之上一个字。 Follow link for more information on how free() works.点击链接了解有关free()工作原理的更多信息。 In our version, we are saving the array size one int (2 words/4 bytes) above the actual array.在我们的版本中,我们将数组大小保存为比实际数组高一个整数(2 个字/4 个字节)。 Your code was wrong because the address you reference is the 3rd element and not the first.您的代码是错误的,因为您引用的地址是第三个元素而不是第一个元素。 You need to pass in the address where the array allocation originated which is ((int*)(*array)) - 1 .您需要传入数组分配起源的地址,即((int*)(*array)) - 1

If you free(*array) , you don't need to *array = NULL after that.如果你free(*array) ,你不需要*array = NULL之后。

Also, you can't cast a (void *) onto an (int *) and assign it to a (double *) .此外,您不能将(void *)(int *)并将其分配给(double *)

Lastly, you can't freeArray(p);最后,你不能freeArray(p); if p is a single pointer since freeArray(double ** array) has a parameter of double double-pointer.如果 p 是单指针,因为freeArray(double ** array)有一个双双指针参数。

Hopefully, this helps.希望这会有所帮助。

You can compare my modified code.您可以比较我修改后的代码。

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


output:输出:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM