【问题标题】:Freeing memory of struct array释放结构数组的内存
【发布时间】:2015-06-07 05:55:55
【问题描述】:

我有两个结构:

struct product {
    char *title;  // Name of the product
    char code[8]; // Max. 7 characters of product ID
    int stock;  // Current stock (number of units)
    double price;  // Price of a single unit
};

struct product_array {
    struct product *arr;
    unsigned int count;
};

我正在将产品添加到 product_array 的功能:

void add_product(struct product_array *pa, const char *title, const char *code,
        int stock, double price) {
    pa->count++;
    struct product* nProduct = malloc(sizeof (struct product));
    if (!nProduct) free(nProduct);
    init_product(nProduct, title, code, stock, price); 

    pa->arr = realloc(pa->arr, (pa->count) * sizeof (struct product));
    if (!pa->arr) free(pa->arr);

    pa->arr[pa->count - 1] = *nProduct;
}

void init_product(struct product *pr, const char *title, const char *code,
        int stock, double price) {
    int titleLen = strlen(title);
    int codeLen = strlen(code);
    char *aTitle = calloc((1 + titleLen) * sizeof (char), 1);
    strncpy(aTitle, title, titleLen);
    char* codePtr = strncpy(pr->code, code, codeLen);
    if (codeLen <= 7)
        *(codePtr + codeLen) = 0;
    else
        *(codePtr + 7) = 0;
    pr->title = aTitle;
    pr->stock = stock;
    pr->price = price;
}

add_product 在 main.c 中是这样工作的

struct product_array pa;
pa.count = 0;
pa.arr = NULL;

struct product p;
init_product(&p, "test", "0000", 1, 0.50);

print_products(&pa);


add_product(&pa, "Product 1", "0000", 0, 10);
add_product(&pa, "Long name, isn't it", "1234567890", 10, 100);
add_product(&pa, "Product 3", "9999999", 0, 20);

print_products(&pa);
remove_all(&pa);

当我试图释放所有分配的内存时,我遇到了问题。这是删除所有功能:

int remove_all(struct product_array *pa) {
    unsigned int i;
    unsigned int until = pa->count;
    struct product *prdPtr = pa->arr;
    struct product *next;
    for (i = 0; i < until; i++) {
        next = prdPtr + 1;
        free(prdPtr->title);
        free(prdPtr);  // this raises error
        prdPtr = next;
    }
    if (pa->arr != NULL) {
        free(pa->arr);
    }    
    pa->count = 0;
    return 1;
}

for 循环溢出,但我现在正试图找出在这种情况下释放内存的逻辑。 在 remove_all 函数中,我想释放 product_array 的所有内存。我正在遍历数组中的每个(结构)产品并释放标题的内存。释放标题记忆后,我试图释放结构产品本身。它在第一次迭代中有效,但是当我谈到第二个元素时,可以释放标题但 free(prdPtr) 会引发 SIGABRT。

我可能缺少什么?为什么我可以释放产品的标题,但不能释放产品本身? 提前感谢您的帮助。

【问题讨论】:

  • 这似乎可行,谢谢!现在我明白了这个错误,数组已经被释放了..

标签: c arrays memory-management memory-leaks struct


【解决方案1】:

pa-&gt;arrstruct product * 而不是 struct product **。 所以你已经为pa-&gt;arr 分配了内存,你应该只释放它一次。 pa-&gt;arr[i] 不是指针,而只是一个结构。

你不应该释放它,但你应该释放任何分配给它的成员的内存,比如title

所以将你的 for 循环更新为

...
for (i = 0; i < until; i++) {
        next = prdPtr + 1;
        free(prdPtr->title); //just free members
        prdPtr = next;
    }
if (pa->arr != NULL) {
    free(pa->arr);
}    
...

编辑:

另请注意,add_product 中有一个不必要的malloc。建议修复:

void add_product(struct product_array *pa, const char *title, const char *code,
        int stock, double price) {
    struct product *pa_tmp;
    pa->count++;
    pa_tmp = realloc(pa->arr, (pa->count) * sizeof (struct product));
    if (pa_tmp == null) {
        /* handle out of memory error */
    }
    pa->arr = pa_tmp;
    init_product(&pa->arr[pa->count - 1], title, code, stock, price); 
}

【讨论】:

  • @user3121023 是的。事实上,prdPtr 也不需要。你可以free(pa-&gt;arr[i].title);
【解决方案2】:

你两次释放同一个内存块:

// this makes pdrPtr to an alias of pa->arr
struct product *prdPtr = pa->arr;

for (i = 0; i < until; i++) {
    ...
    free(prdPtr);  // free prdPtr a.k.a. pa->arr
    ...
}
    // here you free the same oject again.
    free(pa->arr);

删除最后一个free(pa-&gt;arr);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-26
    • 1970-01-01
    相关资源
    最近更新 更多