如果每個結構體包含大小不同的字符串數組,則malloc如何正確地構造一個結構體數組?具有不同大小的結構數組的malloc()結構
因此,每個結構可能有不同的大小,將使它不可能
的realloc(numberOfStructs *的sizeof(structName))
後
的malloc(INITIALSIZE * sizeof(structName)
如何爲此分配內存並跟蹤發生了什麼?
如果每個結構體包含大小不同的字符串數組,則malloc如何正確地構造一個結構體數組?具有不同大小的結構數組的malloc()結構
因此,每個結構可能有不同的大小,將使它不可能
的realloc(numberOfStructs *的sizeof(structName))
後
的malloc(INITIALSIZE * sizeof(structName)
如何爲此分配內存並跟蹤發生了什麼?
我在這裏根據您提供的信息進行猜測。我可以看到想要構造一個數組的realloc
的唯一原因是如果你想向該數組添加更多的結構。這很酷。有很多理由需要這種動態存儲。處理它的最好方法,特別是如果結構本身是動態的,就是將指針保存到這些結構中。例如:
1.數據結構:
typedef struct {
int numberOfStrings;
char ** strings;
}
stringHolder;
typedef struct {
int numberOfStructs;
stringHolder ** structs;
}
structList;
2.管理字符串動態數組:
void createNewStringHolder(stringHolder ** holder) {
(*holder) = malloc(sizeof(stringHolder));
(*holder)->numberOfStrings = 0;
(*holder)->strings = NULL;
}
void destroyStringHolder(stringHolder ** holder) {
// first, free each individual string
int stringIndex;
for (stringIndex = 0; stringIndex < (*holder)->numberOfStrings; stringIndex++)
{ free((*holder)->strings[stringIndex]); }
// next, free the strings[] array
free((*holder)->strings);
// finally, free the holder itself
free((*holder));
}
void addStringToHolder(stringHolder * holder, const char * string) {
int newStringCount = holder->numberOfStrings + 1;
char ** newStrings = realloc(holder->strings, newStringCount * sizeof(char *));
if (newStrings != NULL) {
holder->numberOfStrings = newStringCount;
holder->strings = newStrings;
newStrings[newStringCount - 1] = malloc((strlen(string) + 1) * sizeof(char));
strcpy(newStrings[newStringCount - 1], string);
}
}
3.管理結構的動態數組:
void createNewStructList(structList ** list, int initialSize) {
// create a new list
(*list) = malloc(sizeof(structList));
// create a new list of struct pointers
(*list)->numberOfStructs = initialSize;
(*list)->structs = malloc(initialSize * sizeof(stringHolder *));
// initialize new structs
int structIndex;
for (structIndex = 0; structIndex < initialSize; structIndex++)
{ createNewStringHolder(&((*list)->structs[structIndex])); }
}
void destroyStructList(structList ** list) {
// destroy each struct in the list
int structIndex;
for (structIndex = 0; structIndex < (*list)->numberOfStructs; structIndex++)
{ destroyStringHolder(&((*list)->structs[structIndex])); }
// destroy the list itself
free((*list));
}
stringHolder * addNewStructToList(structList * list) {
int newStructCount = list->numberOfStructs + 1;
size_t newSize = newStructCount * sizeof(stringHolder *);
stringHolder ** newList = realloc(list->structs, newSize);
if (newList != NULL) {
list->numberOfStructs = newStructCount;
list->structs = newList;
createNewStringHolder(&(newList[newStructCount - 1]));
return newList[newStructCount - 1];
}
return NULL;
}
4。主程序:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (int argc, char * argv[]) {
structList * allHolders;
createNewStructList(&allHolders, 10);
addStringToHolder(allHolders->structs[4], "The wind took it");
addStringToHolder(allHolders->structs[4], "Am I not merciful?");
addStringToHolder(allHolders->structs[7], "Aziz, Light!");
printf("%s\n", allHolders->structs[4]->strings[0]); // The wind took it
printf("%s\n", allHolders->structs[4]->strings[1]); // Am I not merciful?
printf("%s\n", allHolders->structs[7]->strings[0]); // Aziz, Light!
stringHolder * newHolder = addNewStructToList(allHolders);
addStringToHolder(newHolder, "You shall not pass!");
printf("%s\n", newHolder->strings[0]); // You shall not pass!
printf("%s\n", allHolders->structs[10]->strings[0]); // You shall not pass!
destroyStructList(&allHolders);
return 0;
}
如果你的結構有一個char *,它將佔用一個指針的大小。如果它有一個字符[200],則佔用兩百個字節。
您一般不會。有兩個原因你可能想要做到這一點:
free()
將釋放整個內存塊。但是,除非你有一個特殊的情況,也不是非常引人注目的,因爲沉重的缺點,這種方法:
如果你這樣做,那麼block[i]
是沒有意義的。你還沒有分配數組。沒有辦法確定你的下一個結構是從哪裏開始的,沒有檢查結構,也沒有關於塊中結構的大小/位置的外部信息。
它不是那麼清楚你struct
類型的聲明方式。 C99具有這樣的事情一個特殊的構建體,被稱爲struct
的柔性陣列成員:
作爲一個特殊的情況下,與一個以上的命名 構件的結構可以具有一個不完整的陣列 類型的 的最後一個元素;這被稱爲靈活數組 成員。
你可以做類似
typedef struct myString myString;
struct myString { size_t len; char c[]; };
然後,您可以用
size_t x = 35;
myString* s = malloc(sizeof(myString) + x);
s->len = x;
分配這樣的野獸,用
size_t y = 350;
{
myString* tmp = realloc(s, sizeof(myString) + y);
if (!tmp) abort(); // or whatever
tmp->len = y;
}
s = tmp;
重新分配它爲了舒適地使用這個你越'd可能會更好地將其包含到宏或inli中ne功能。
每個結構的大小是固定的。如果你的結構中有一個可以溢出其大小的數組,那麼這是另一回事,但編譯器不關心。 – Mehrdad 2011-02-13 03:56:14
另一個故事是我的問題和疑問:) – jarryd 2011-02-13 03:59:12
你的結構是什麼樣子的? – jswolf19 2011-02-13 03:59:44