简体   繁体   English

C:c中分配的空闲内存

[英]C: free memory allocated in c

suppose i have a struct: 假设我有一个结构:

typedef struct{
    char *ID;
    char *name;
    float price;
    int quantity;
} Generic_Properties;

now if i have used malloc to allocate space in the heap for it and saved the address in a pointer, lets call him p1 . 现在如果我已经使用malloc为堆中的空间分配空间并将地址保存在指针中,那么就叫它p1 now i want to free that specific memory block, is it enough to just declare free(p1) : 现在我想释放那个特定的内存块,是否足以宣布free(p1)

free(p1);

or do i need to separately free ID and name pointers, because I used malloc to allocated space for the string they're pointing to? 或者我需要单独释放ID和名称指针,因为我使用malloc为他们指向的字符串分配空间?

The rule is, malloc and free should come in pair. 规则是, mallocfree应该成对出现。 Free everything thing that is malloc ed exactly once. 免费所有东西都是malloc ed恰好一次。

char name[] = "some_name";
Generic_Properties *p1 = malloc(...);  /* 1 */
p1->ID = malloc(...); /* 2 */
p1->name = name;
...
...
/* free(p1->name); Don't do this, p1->name was not allocated with malloc*/
free(p1->ID);  /* 2' */
free(p1); /* 1' */
/* if(p1 && p1->name[0] == '?') {} don't dereference p1 after it is freed. It is dangling now */
...
...
/* free(p1); don't free p1 again as it is already freed and is dangling. */
p1 = NULL;
free(p1); /* OK */

or do i need to separately free ID and name pointers, because I used malloc to allocated space for the string they're pointing to? 或者我需要单独释放ID和名称指针,因为我使用malloc为他们指向的字符串分配空间?

As pointed out by Mohit Jain, every call to malloc must be followed by a free call, but in this case (see comments bellow) nothing prevents you to reserve space for everything in a single call: 正如Mohit Jain所指出的,每次对malloc调用都必须跟随一个free调用,但在这种情况下(参见下面的评论)没有什么能阻止你在一次调用中为所有内容保留空间:

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

typedef struct{
    char *ID;
    char *name;
    float price;
    int quantity;
} Generic_Properties;

int main(void)
{
    Generic_Properties *x = malloc(sizeof(*x) + 100);
    x->ID = (char *)(x + 1);
    x->name = x->ID + 50;

    strcpy(x->ID, "00001");
    strcpy(x->name, "David");
    printf("%s %s\n", x->ID, x->name);
    free(x);
    return 0;
}

A more object-oriented way of handling this sort of structure is to define functions for both allocating and freeing such structures. 处理这种结构的更面向对象的方法是定义分配和释放这种结构的函数。

(Improved version of this code) (此代码的改进版本)

// Allocate a GP object
Generic_Properties * create_GP()
{
    Generic_Properties *  p;

    p = malloc(sizeof(Generic_Properties));
    memset(p, 0, sizeof(*p));
    return p;
}

// Deallocate a GP object
void free_GP(Generic_Properties *p)
{
    if (p == NULL)
        return;

    free(p->ID);
    p->ID = NULL;

    free(p->name);
    p->name = NULL;

    free(p);
}

Addendum 附录

If you want to combine this approach with @Alter Mann 's approach, you can do something like this: 如果你想把这种方法与@Alter Mann的方法结合起来,你可以这样做:

// Allocate a GP object
Generic_Properties * create_GP2(const char *id, const char *name)
{
    size_t                idLen;
    size_t                nameLen;
    Generic_Properties *  p;

    // Reserve space for GP, GP.ID, and GP.name
    //  all in one malloc'd block
    idLen = strlen(id) + 1;
    nameLen = strlen(name) + 1;
    p = malloc(sizeof(Generic_Properties) + idLen + nameLen);
    memset(p, 0, sizeof(*p));

    // Save the ID
    p->ID = (char *)p + sizeof(Generic_Properties);
    memcpy(p->ID, id, idLen);

    // Save the name
    p->name = p->ID + idLen;
    memcpy(p->name, name, nameLen);
    return p;
}

// Deallocate a GP object
void free_GP2(Generic_Properties *p)
{
    free(p);
}

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

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