假设我有一个结构:
typedef struct{
char *ID;
char *name;
float price;
int quantity;
} Generic_Properties;
现在如果我已经使用malloc为堆中的空间分配空间并将地址保存在指针中,那么就叫他p1
。现在我想释放那个特定的内存块,只需声明free(p1)
:
free(p1);
或者我是否需要单独释放ID和名称指针,因为我使用malloc为它们指向的字符串分配了空间?
答案 0 :(得分:10)
规则是,malloc
和free
应成对出现。免费提供malloc
一次的所有内容。
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 */
答案 1 :(得分:2)
或者我需要单独释放ID和名称指针,因为我使用过 malloc为他们指向的字符串分配空间?
正如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;
}
答案 2 :(得分:1)
更加面向对象的处理这种结构的方法是定义分配和释放这种结构的函数。
(此代码的改进版本)
// 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);
}
<强>附录强>
如果您想将此方法与@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);
}