如果每个struct包含一个大小不一的字符串数组,那么malloc如何正确构造一个结构数组?
因此,每个结构可能具有不同的大小,并且无法
realloc(numberOfStructs * sizeof(structName))
之后
malloc(initialSize * sizeof(structName)
如何为此分配内存并跟踪发生的情况?
答案 0 :(得分:4)
如果你的结构有一个char *,它占用一个指针的大小。如果它有char [200],则需要200个字节。
答案 1 :(得分:3)
我根据您提供的信息在此做出一些猜测。我想看到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;
}
答案 2 :(得分:1)
一般来说,你没有。您可能希望这样做有两个原因:
free()
就会释放整个内存块。但除非你有特殊情况,否则两者都没有引人注目,因为这种做法存在严重缺陷:
如果你这样做,那么block[i]
毫无意义。您尚未分配数组。如果没有检查结构或者在块中有关于结构的大小/位置的外部信息,就无法确定下一个结构的起始位置。
答案 3 :(得分:0)
您的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;
为了更舒适地使用它,你可能最好把它包装成宏或内联函数。