正在释放的指针未分配给 C 中的字符串数组

Pointer being freed was not allocated for array of strings in C

我知道这个问题存在于其他地方,例如:

error: pointer being freed was not allocated

但是,我仍然很困惑。错误似乎与 "modifying the original pointer returned by malloc" 和 "failing to malloc before freeing" 之类的东西有关。我只是不明白这些原因如何适用于我的程序。

我正在写一个动态分配的字符串数组:

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

#define NLETTERS 25

typedef struct {
    char** array;
    size_t used;
    size_t size;
} array_t;

array_t* initArray(size_t initialSize) {
    array_t* a = malloc(sizeof(array_t));
    a->array = malloc(initialSize*sizeof(char*));
    a->used = 0;
    a->size = initialSize;

    int i;
    for(i = 0; i < initialSize; i++) {
        a->array[i] = malloc(sizeof(char) * NLETTERS);
    }

    return a;
}

void insertArray(array_t *a, char* element) {
    if (a->used == a->size) {
        a->size *= 2;

        a->array = realloc(a->array, a->size * sizeof(char*));

        int i;
        for(i = (int)a->used; i < a->size; i++) {
            a->array[i] = malloc(sizeof(char) * NLETTERS);
        }
    }
    a->array[a->used++] = element;
}

void freeArray(array_t *a) {
    int i;
    for(i = 0; i < a->size; i++) {
        free(a->array[i]);
    }

    free(a->array);
    free(a);
    a->array = NULL;
    a->used = a->size = 0;
}

void print_array(array_t *a) {
    int i;
    for(i = 0; i < a->size; i++) {
        printf("%s\n", a->array[i]);
    }
}

int main(int argc, const char * argv[]) {
    array_t *a;
    a = initArray(2);
    insertArray(a, "hello");
    insertArray(a, "how are you");
    print_array(a);
    insertArray(a, "yup");
    insertArray(a, "you know it");
    print_array(a);

    freeArray(a);

    return 0;
}

当我尝试 "free" 时,出现错误:"pointer being freed was not allocated" 就在

free(a->array[0]) 

在 freeArray() 中 for 循环的第一次迭代中;

将不胜感激。

在你的代码中,通过说

  a->array[a->used++] = element;

您正在用 malloc() 覆盖分配的内存,因此稍后将其传递给 free() 会导致问题。

相关,引用C11,章节§7.22.3.3,free函数,(强调我的)

The free function causes the space pointed to by ptr to be deallocated, that is, made available for further allocation. If ptr is a null pointer, no action occurs. Otherwise, if the argument does not match a pointer earlier returned by a memory management function, or if the space has been deallocated by a call to free or realloc, the behavior is undefined.

此外,稍后,这会导致 memory leak,因为 malloc() 分配的内存实际上没有得到 free()-d。

解决方法:你应该使用strcpy()复制内容分配的内存。

问题的根源是这条线:

a->array[a->used++] = element;

它有两个问题:

  1. 内存泄漏。 malloc()返回的记忆丢失。

  2. 它指向用于字符串文字的只读内存,当您在其上调用 free 时会导致问题。

将该行替换为

strcpy(a->array[a->used++], element);

我看到两个问题:-

  1. a->array[a->used++] = element;
    您已经分配了内存但没有使用它,您再次将它指向其他某个位置导致内存泄漏。所以将其更改为:-

    strcpy(a->array[a->used++], element);

  2. 像这样更改 FreeArray(您正在释放内存而不是使用它,这会导致段错误)。

    void freeArray(array_t *a) {
        int i;
        for(i = 0; i < a->size; i++) {
            free(a->array[i]);
        }
    
        free(a->array);
        a->array = NULL;
        a->used = a->size = 0;
        free(a);
    }