如何为某些结构元素分配内存



我想为结构中的一些元素分配内存,这些元素是指向其他小结构的指针。如何以最佳方式分配和取消分配内存?

例如:

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_STRUCTDatatypeN元素,它们就不需要以任何方式重新分配,任何其他代码也不需要在它们中的任何一个上执行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();

相关内容

  • 没有找到相关文章