具有不同大小结构的结构数组的malloc()

具有不同大小结构的结构数组的malloc(),c,malloc,realloc,C,Malloc,Realloc,如果每个结构都包含大小不同的字符串数组,那么malloc如何正确地创建结构数组 因此,每个结构可能有不同的大小,因此无法 realloc(numberOfStructs*sizeof(structName)) 之后 malloc(initialSize*sizeof(structName) 如何为此分配内存并跟踪发生的情况?如果您的结构有一个char*,它将占用一个指针的大小。如果它有一个char[200],它将占用两百字节。如果您的结构有一个char*,它将占用一个指针的大小。如果它有一个ch

如果每个结构都包含大小不同的字符串数组,那么malloc如何正确地创建结构数组

因此,每个结构可能有不同的大小,因此无法

realloc(numberOfStructs*sizeof(structName))

之后

malloc(initialSize*sizeof(structName)


如何为此分配内存并跟踪发生的情况?

如果您的结构有一个char*,它将占用一个指针的大小。如果它有一个char[200],它将占用两百字节。

如果您的结构有一个char*,它将占用一个指针的大小。如果它有一个char[200],它会占用200个字节。

通常情况下,您不需要这样做。您需要这样做的原因有两个:

  • 这样一个
    free()
    将释放整个内存块
  • 避免内部内存碎片
  • 但除非你有特殊情况,否则这两种方法都不是很有说服力,因为这种方法有一个致命的缺点:


    如果您这样做,那么
    block[i]
    没有任何意义。您尚未分配数组。如果不检查结构或没有关于块中结构的大小/位置的外部信息,就无法判断下一个结构从何处开始。

    通常情况下,您不知道。您可能希望这样做的原因有两个:

  • 这样一个
    free()
    将释放整个内存块
  • 避免内部内存碎片
  • 但除非你有特殊情况,否则这两种方法都不是很有说服力,因为这种方法有一个致命的缺点:


    如果您这样做,那么
    block[i]
    没有意义。您没有分配数组。如果不检查结构或没有关于块中结构的大小/位置的外部信息,就无法判断下一个结构从何处开始。

    根据您提供的信息,我在这里进行一些猜测。我能看到wanti的唯一原因是ng to
    realloc
    如果你想在数组中添加更多的结构,则需要一个结构数组。这很酷。有很多理由需要这种动态存储。处理这种存储的最佳方法,尤其是当结构本身是动态的时,就是保留一个指向这些结构的指针数组。例如:

    1.数据结构:

    2.管理字符串的动态数组:

    void createNewStringHolder(stringHolder**holder){
    (*持有人)=malloc(sizeof(stringHolder));
    (*持有者)->numberOfStrings=0;
    (*holder)->strings=NULL;
    }
    空支架(支架**支架){
    //首先,释放每个单独的字符串
    int-stringIndex;
    对于(stringIndex=0;stringIndex<(*holder)->numberOfStrings;stringIndex++)
    {free((*holder)->strings[stringIndex]);}
    //接下来,释放字符串[]数组
    自由((*持有者)->字符串);
    //最后,释放持有者本身
    自由((*持有人));
    }
    void addStringToHolder(stringHolder*holder,常量字符*string){
    int newStringCount=holder->numberOfStrings+1;
    char**newStrings=realloc(holder->strings,newStringCount*sizeof(char*));
    if(新闻字符串!=NULL){
    holder->numberOfStrings=newStringCount;
    持有者->字符串=新闻字符串;
    newStrings[newStringCount-1]=malloc((strlen(string)+1)*sizeof(char));
    strcpy(newStrings[newStringCount-1],string);
    }
    }
    
    3.管理动态结构阵列:

    void createNewStructList(structList**list,int initialSize){
    //创建一个新列表
    (*list)=malloc(sizeof(structList));
    //创建一个新的结构指针列表
    (*列表)->numberOfStructs=初始大小;
    (*list)->structs=malloc(initialSize*sizeof(stringHolder*));
    //初始化新结构
    int结构索引;
    对于(structIndex=0;structIndexstructs[structIndex]);}
    }
    作废销毁结构列表(结构列表**列表){
    //销毁列表中的每个结构
    int结构索引;
    对于(structIndex=0;structIndex<(*列表)->numberOfStructs;structIndex++)
    {destroyStringHolder(&((*list)->structs[structIndex]);}
    //销毁列表本身
    免费((*列表));
    }
    stringHolder*添加新结构列表(structList*列表){
    int newStructCount=list->numberOfStructs+1;
    size_t newSize=新结构数量*sizeof(stringHolder*);
    stringHolder**newList=realloc(列表->结构,新闻大小);
    if(newList!=NULL){
    列表->numberOfStructs=newStructCount;
    list->structs=newList;
    createNewStringHolder(&(newList[newStructCount-1]);
    返回newList[newStructCount-1];
    }
    返回NULL;
    }
    
    4.主程序:

    #包括
    #包括
    #包括
    int main(int argc,char*argv[]){
    名单*所有持有人;
    createNewStructList(&allHolders,10);
    addStringToHolder(allHolders->structs[4],“风带走了它”);
    addStringToHolder(allHolders->structs[4],“我不仁慈吗?”;
    addStringToHolder(allHolders->structs[7],“Aziz,Light!”);
    printf(“%s\n”,allHolders->structs[4]->strings[0]);//风把它带走了
    printf(“%s\n”,allHolders->structs[4]->strings[1]);//我不仁慈吗?
    printf(“%s\n”,allHolders->structs[7]->strings[0]);//阿齐兹,轻!
    stringHolder*newHolder=addNewStructToList(所有持有人);
    addStringToHolder(新的Holder,“你不能通过!”);
    printf(“%s\n”,newHolder->strings[0]);//您不能通过!
    printf(“%s\n”,allHolders->structs[10]->strings[0]);//您不能通过!
    清单(和所有持有人);
    返回0;
    }
    
    根据您提供的信息,我在这里做了一些猜测。我想
    realloc
    一个结构数组的唯一原因是如果您想
    typedef struct {
        int numberOfStrings;
        char ** strings;
    }
    stringHolder;
    
    typedef struct {
        int numberOfStructs;
        stringHolder ** structs;
    }
    structList;
    
    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);
        }
    }
    
    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;
    }
    
    #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;
    }
    
    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;