【问题标题】:Pointer being freed was not allocated for array of strings in C未为 C 中的字符串数组分配被释放的指针
【发布时间】:2017-04-12 23:05:00
【问题描述】:

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

pointer being freed was not allocated in C error: pointer being freed was not allocated

但是,我还是很困惑。错误似乎与“修改 malloc 返回的原始指针”和“在释放之前未能使用 malloc”之类的事情有关。我只是不明白这些原因如何适用于我的程序。

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

#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(a->array[0]) 

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

我们将不胜感激。

【问题讨论】:

  • 你是在暗示我的 realloc 不正确吗?应该改成什么?我真的不明白该链接下的修复是什么。
  • 请注意,在insertArray() 中,您有成语old_ptr = realloc(old_ptr, new_size);。这是不好的。如果(何时!)realloc() 失败,您会泄漏内存,因为old_ptr 被 NULL 覆盖,因此您不能再释放旧内存,即使它仍然被分配。使用new_ptr = realloc(old_ptr, new_size); if (new_ptr == NULL) { …report error, etc… } old_ptr = new_ptr;(通常也使用old_size = new_size;)。

标签: c pointers memory-management free dynamic-memory-allocation


【解决方案1】:

在你的代码中,通过说

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

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

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

free函数导致ptr指向的空间被释放,也就是制造 可用于进一步分配。如果ptr 是空指针,则不会发生任何操作。否则,如果 该参数与内存管理先前返回的指针不匹配 函数,或者如果空间已通过调用 free 或 realloc 释放,则 行为未定义。

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

解决方案:您应该使用strcpy() 将内容复制到分配的内存中。

【讨论】:

    【解决方案2】:

    问题的根源在于这一行:

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

    它有两个问题:

    1. 它会泄漏内存。 malloc()返回的内存丢失了。

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

    替换该行
    strcpy(a->array[a->used++], element);
    

    【讨论】:

      【解决方案3】:

      我看到两个问题:-

      1. a-&gt;array[a-&gt;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);
        }
        

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-11
        • 1970-01-01
        • 2014-02-23
        • 1970-01-01
        • 1970-01-01
        • 2014-06-07
        • 1970-01-01
        相关资源
        最近更新 更多