我想为结构中的一些元素分配内存,这些元素是指向其他小结构的指针。如何以最佳方式分配和取消分配内存?
例如:
typedef struct _SOME_STRUCT {
PDATATYPE1 PDatatype1;
PDATATYPE2 PDatatype2;
PDATATYPE3 PDatatype3;
.......
PDATATYPE12 PDatatype12;
} SOME_STRUCT, *PSOME_STRUCT;
我想为PDatatype1,3,4,6,7,9,11分配内存。我可以用单个malloc分配内存吗?或者,只为这些元素分配内存的最佳方式是什么?如何释放分配的整个内存?
有一个技巧,它允许使用单个malloc
,但也必须与使用更标准的多个malloc
方法进行权衡。
如果[并且onlyIf],一旦分配了SOME_STRUCT
的DatatypeN
元素,它们就不需要以任何方式重新分配,任何其他代码也不需要在它们中的任何一个上执行free
,您可以执行以下操作[假设PDATATYPEn
指向DATATYPEn
]:
PSOME_STRUCT
alloc_some_struct(void)
{
size_t siz;
void *vptr;
PSOME_STRUCT sptr;
// NOTE: this optimizes down to a single assignment
siz = 0;
siz += sizeof(DATATYPE1);
siz += sizeof(DATATYPE2);
siz += sizeof(DATATYPE3);
...
siz += sizeof(DATATYPE12);
sptr = malloc(sizeof(SOME_STRUCT) + siz);
vptr = sptr;
vptr += sizeof(SOME_STRUCT);
sptr->Pdatatype1 = vptr;
// either initialize the struct pointed to by sptr->Pdatatype1 here or
// caller should do it -- likewise for the others ...
vptr += sizeof(DATATYPE1);
sptr->Pdatatype2 = vptr;
vptr += sizeof(DATATYPE2);
sptr->Pdatatype3 = vptr;
vptr += sizeof(DATATYPE3);
...
sptr->Pdatatype12 = vptr;
vptr += sizeof(DATATYPE12);
return sptr;
}
然后,当你完成时,只需做free(sptr)
。
以上的sizeof
应足以为子结构提供适当的对齐。如果没有,则必须将它们替换为提供必要对齐的宏(例如SIZEOF
)。(例如)对于8字节对齐,类似于:
#define SIZEOF(_siz) (((_siz) + 7) & ~0x07)
注意:虽然可以做到这一切,但它更常见于可变长度字符串结构,如:
struct mystring {
int my_strlen;
char my_strbuf[0];
};
struct mystring {
int my_strlen;
char *my_strbuf;
};
是否值得[潜在的]脆弱性(即有人忘记并对单个元素进行realloc/free
)是有争议的。如果单个malloc
对您来说是高优先级的,那么更干净的方法是嵌入实际的结构,而不是指向它们的指针。
否则,只需执行[更]标准的方式,执行12个单独的malloc
调用,然后执行12个free
调用。
尽管如此,它是一种可行的技术,尤其是在内存受限的小型系统上。
以下是涉及每个元素分配的[更]常见方法:
PSOME_STRUCT
alloc_some_struct(void)
{
void *vptr;
PSOME_STRUCT sptr;
sptr = malloc(sizeof(SOME_STRUCT));
// either initialize the struct pointed to by sptr->Pdatatype1 here or
// caller should do it -- likewise for the others ...
sptr->Pdatatype1 = malloc(sizeof(DATATYPE1));
sptr->Pdatatype2 = malloc(sizeof(DATATYPE2));
sptr->Pdatatype3 = malloc(sizeof(DATATYPE3));
...
sptr->Pdatatype12 = malloc(sizeof(DATATYPE12));
return sptr;
}
void
free_some_struct(PSOME_STRUCT sptr)
{
free(sptr->Pdatatype1);
free(sptr->Pdatatype2);
free(sptr->Pdatatype3);
...
free(sptr->Pdatatype12);
free(sptr);
}
如果您的结构包含其他结构作为元素而不是指针,您可以一次性为组合结构分配内存:
typedef struct _SOME_STRUCT {
DATATYPE1 Datatype1;
DATATYPE2 Datatype2;
DATATYPE3 Datatype3;
.......
DATATYPE12 Datatype12;
} SOME_STRUCT, *PSOME_STRUCT;
PSOME_STRUCT p = (PSOME_STRUCT)malloc(sizeof(SOME_STRUCT));
// Or without malloc:
PSOME_STRUCT p = new SOME_STRUCT();