Es ist ein Trick, der einen einzigen malloc
erlaubt, aber das muss auch dagegen abgewogen werden, einen mehrfachen Standard malloc
Ansatz zu tun.
Wenn [und nur wenn], sobald die DatatypeN
Elemente SOME_STRUCT
zugeordnet sind, tun sie nicht in irgendeiner Weise neu verteilt werden müssen, noch haben jeder anderer Code tun, um ein free
auf einem sie, können Sie die folgende [die Annahme, dass PDATATYPEn
Punkte DATATYPEn
] tun:
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;
}
Dann wird das, wenn Sie fertig sind, nur free(sptr)
tun.
Die sizeof
über sollte ausreichend sein, um eine ordnungsgemäße Ausrichtung für die Unterstrukturen bereitzustellen. Wenn nicht, müssen Sie sie durch ein Makro ersetzen (z. B. SIZEOF
), das die erforderliche Ausrichtung bietet. (ZB) für 8-Byte-Ausrichtung, so etwas wie:
#define SIZEOF(_siz) (((_siz) + 7) & ~0x07)
Hinweis: Während es möglich ist, all dies zu tun, und es ist häufiger für Dinge wie variabler Länge Zeichenfolge structs wie:
struct mystring {
int my_strlen;
char my_strbuf[0];
};
struct mystring {
int my_strlen;
char *my_strbuf;
};
Es ist fraglich, ob es die [potentielle] Fragilität wert ist (dh jemand vergisst und macht die realloc/free
auf den einzelnen Elementen). Der sauberere Weg wäre, die tatsächlichen Strukturen anstelle der Zeiger auf sie einzubetten, wenn die einzelne malloc
eine hohe Priorität für Sie hat.
Ansonsten tun Sie einfach den [mehr] Standard Weg und tun die 12 individuellen malloc
Anrufe und später die 12 free
Anrufe.
Dennoch ist es ist eine praktikable Technik, insbesondere auf kleinen Speicher beschränkt Systeme. Hier
ist die [mehr] gewohnte Weise beteiligt pro-Element Zuweisungen:
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);
}
Wenn es andere structs hat statt ihren Zeiger es sie direkt durch 'SOME_STRUCT' verwenden kann, ohne das Zuweisen von Speicher, kann ich nicht ? – Ron
Ja, wenn Sie eine Variable wie folgt definieren: 'SOME_STRUCT s;' –
Aber ich muss nur Zeiger verwenden. – Ron