如何创建一个动态大小的结构体数组?

时间:2022-09-20 13:15:14

I know how to create an array of structs but with a predefined size. However is there a way to create a dynamic array of structs such that the array could get bigger?

我知道如何创建一个具有预定义大小的结构数组。然而,是否有一种方法可以创建一个结构的动态数组,这样数组就可以变得更大?

For example:

例如:

    typedef struct
    {
        char *str;
    } words;

    main()
    {
        words x[100]; // I do not want to use this, I want to dynamic increase the size of the array as data comes in.
    }

Is this possible?

这是可能的吗?


I've researched this: words* array = (words*)malloc(sizeof(words) * 100);

我研究过:words* array = (words*)malloc(sizeof(words) * 100);

I want to get rid of the 100 and store the data as it comes in. Thus if 76 fields of data comes in, I want to store 76 and not 100. I'm assuming that I don't know how much data is coming into my program. In the struct I defined above I could create the first "index" as:

我想去掉100,然后在数据进来的时候储存起来。因此,如果有76个数据字段,我想存储76个而不是100个。我假设我不知道有多少数据进入我的程序。在上面定义的结构中,我可以创建第一个“索引”为:

    words* array = (words*)malloc(sizeof(words));

However I want to dynamically add elements to the array after. I hope I described the problem area clearly enough. The major challenge is to dynamically add a second field, at least that is the challenge for the moment.

但是,我想在后面动态地向数组中添加元素。我希望我把问题描述得足够清楚。主要的挑战是动态添加第二个字段,至少这是目前的挑战。


I've made a little progress however:

然而,我有了一点进步:

    typedef struct {
        char *str;
    } words;

    // Allocate first string.
    words x = (words) malloc(sizeof(words));
    x[0].str = "john";

    // Allocate second string.
    x=(words*) realloc(x, sizeof(words));
    x[1].FirstName = "bob";

    // printf second string.
    printf("%s", x[1].str); --> This is working, it's printing out bob.

    free(x); // Free up memory.

    printf("%s", x[1].str); --> Not working since its still printing out BOB even though I freed up memory. What is wrong?

I did some error checking and this is what I found. If after I free up memory for x I add the following:

我做了一些错误检查,这就是我发现的。如果在释放x的内存后,我添加以下内容:

    x=NULL;

then if I try to print x I get an error which is what I want. So is it that the free function is not working, at least on my compiler? I'm using DevC??

如果我尝试打印x,我会得到一个错误,这是我想要的。那么,至少在我的编译器上,*函数没有工作吗?我用DevC ? ?


Thanks, I understand now due to:

谢谢,因为:

FirstName is a pointer to an array of char which is not being allocated by the malloc, only the pointer is being allocated and after you call free, it doesn't erase the memory, it just marks it as available on the heap to be over written later. – MattSmith

FirstName是指向未被malloc分配的char数组的指针,只有指针正在被分配,在您调用free之后,它不会擦除内存,它只是将其标记为在堆上可用的,稍后将其写完。——MattSmith

Update

I'm trying to modularize and put the creation of my array of structs in a function but nothing seems to work. I'm trying something very simple and I don't know what else to do. It's along the same lines as before, just another function, loaddata that is loading the data and outside the method I need to do some printing. How can I make it work? My code is as follows:

我试图模块化并将我的结构数组的创建放在一个函数中,但似乎没有任何效果。我正在尝试一些非常简单的东西,我不知道还能做什么。它和以前一样,只是另一个函数loaddata,加载数据,在方法之外我需要打印。我如何让它工作?我的代码如下:

    # include <stdio.h>
    # include <stdlib.h>
    # include <string.h>
    # include <ctype.h>

    typedef struct
    {
        char *str1;
        char *str2;
    } words;

    void LoadData(words *, int *);

    main()
    {
        words *x;
        int num;

        LoadData(&x, &num);

        printf("%s %s", x[0].str1, x[0].str2);
        printf("%s %s", x[1].str1, x[1].str2);

        getch();
    }//

    void LoadData(words *x, int * num)
    {
        x = (words*) malloc(sizeof(words));

        x[0].str1 = "johnnie\0";
        x[0].str2 = "krapson\0";

        x = (words*) realloc(x, sizeof(words)*2);
        x[1].str1 = "bob\0";
        x[1].str2 = "marley\0";

        *num=*num+1;
    }//

This simple test code is crashing and I have no idea why. Where is the bug?

这个简单的测试代码正在崩溃,我不知道为什么。错误在哪里?

11 个解决方案

#1


35  

You've tagged this as C++ as well as C.

您已经将它标记为c++和C。

If you're using C++ things are a lot easier. The standard template library has a template called vector which allows you to dynamically build up a list of objects.

如果你用的是c++,事情就简单多了。标准模板库有一个名为vector的模板,它允许您动态地构建对象列表。

#include <stdio.h>
#include <vector>

typedef std::vector<char*> words;

int main(int argc, char** argv) {

        words myWords;

        myWords.push_back("Hello");
        myWords.push_back("World");

        words::iterator iter;
        for (iter = myWords.begin(); iter != myWords.end(); ++iter) {
                printf("%s ", *iter);
        }

        return 0;
}

If you're using C things are a lot harder, yes malloc, realloc and free are the tools to help you. You might want to consider using a linked list data structure instead. These are generally easier to grow but don't facilitate random access as easily.

如果您正在使用C语言,那么事情就会变得更加困难,是的,malloc、realloc和free都是帮助您的工具。您可能需要考虑使用链表数据结构。这些通常都比较容易实现,但不方便随意访问。

#include <stdio.h>
#include <stdlib.h>

typedef struct s_words {
        char* str;
        struct s_words* next;
} words;

words* create_words(char* word) {
        words* newWords = malloc(sizeof(words));
        if (NULL != newWords){
                newWords->str = word;
                newWords->next = NULL;
        }
        return newWords;
}

void delete_words(words* oldWords) {
        if (NULL != oldWords->next) {
                delete_words(oldWords->next);
        }
        free(oldWords);
}

words* add_word(words* wordList, char* word) {
        words* newWords = create_words(word);
        if (NULL != newWords) {
                newWords->next = wordList;
        }
        return newWords;
}

int main(int argc, char** argv) {

        words* myWords = create_words("Hello");
        myWords = add_word(myWords, "World");

        words* iter;
        for (iter = myWords; NULL != iter; iter = iter->next) {
                printf("%s ", iter->str);
        }
        delete_words(myWords);
        return 0;
}

Yikes, sorry for the worlds longest answer. So WRT to the "don't want to use a linked list comment":

哎呀,对不起,世界上最长的答案。因此,WRT到“不要使用链表注释”:

#include <stdio.h>  
#include <stdlib.h>

typedef struct {
    char** words;
    size_t nWords;
    size_t size;
    size_t block_size;
} word_list;

word_list* create_word_list(size_t block_size) {
    word_list* pWordList = malloc(sizeof(word_list));
    if (NULL != pWordList) {
        pWordList->nWords = 0;
        pWordList->size = block_size;
        pWordList->block_size = block_size;
        pWordList->words = malloc(sizeof(char*)*block_size);
        if (NULL == pWordList->words) {
            free(pWordList);
            return NULL;    
        }
    }
    return pWordList;
}

void delete_word_list(word_list* pWordList) {
    free(pWordList->words);
    free(pWordList);
}

int add_word_to_word_list(word_list* pWordList, char* word) {
    size_t nWords = pWordList->nWords;
    if (nWords >= pWordList->size) {
        size_t newSize = pWordList->size + pWordList->block_size;
        void* newWords = realloc(pWordList->words, sizeof(char*)*newSize); 
        if (NULL == newWords) {
            return 0;
        } else {    
            pWordList->size = newSize;
            pWordList->words = (char**)newWords;
        }

    }

    pWordList->words[nWords] = word;
    ++pWordList->nWords;


    return 1;
}

char** word_list_start(word_list* pWordList) {
        return pWordList->words;
}

char** word_list_end(word_list* pWordList) {
        return &pWordList->words[pWordList->nWords];
}

int main(int argc, char** argv) {

        word_list* myWords = create_word_list(2);
        add_word_to_word_list(myWords, "Hello");
        add_word_to_word_list(myWords, "World");
        add_word_to_word_list(myWords, "Goodbye");

        char** iter;
        for (iter = word_list_start(myWords); iter != word_list_end(myWords); ++iter) {
                printf("%s ", *iter);
        }

        delete_word_list(myWords);

        return 0;
}

#2


11  

If you want to dynamically allocate arrays, you can use malloc from stdlib.h.

如果希望动态分配数组,可以使用stdlib.h中的malloc。

If you want to allocate an array of 100 elements using your words struct, try the following:

如果您想使用word struct分配一个包含100个元素的数组,请尝试以下操作:

words* array = (words*)malloc(sizeof(words) * 100);

The size of the memory that you want to allocate is passed into malloc and then it will return a pointer of type void (void*). In most cases you'll probably want to cast it to the pointer type you desire, which in this case is words*.

要分配的内存的大小被传递给malloc,然后它将返回一个类型为void (void*)的指针。在大多数情况下,您可能希望将它转换为您想要的指针类型,在本例中是words*。

The sizeof keyword is used here to find out the size of the words struct, then that size is multiplied by the number of elements you want to allocate.

这里使用sizeof关键字来查找单词struct的大小,然后将该大小乘以要分配的元素的数量。

Once you are done, be sure to use free() to free up the heap memory you used in order to prevent memory leaks:

完成后,请确保使用free()释放用于防止内存泄漏的堆内存:

free(array);

If you want to change the size of the allocated array, you can try to use realloc as others have mentioned, but keep in mind that if you do many reallocs you may end up fragmenting the memory. If you want to dynamically resize the array in order to keep a low memory footprint for your program, it may be better to not do too many reallocs.

如果您想更改已分配数组的大小,您可以尝试使用realloc,就像其他人提到的那样,但是请记住,如果您执行了许多reallocs,那么您可能最终导致内存碎片化。如果您想动态地调整数组的大小以保持程序的低内存占用,最好不要做太多的reallocs。

#3


5  

This looks like an academic exercise which unfortunately makes it harder since you can't use C++. Basically you have to manage some of the overhead for the allocation and keep track how much memory has been allocated if you need to resize it later. This is where the C++ standard library shines.

这看起来像是一个学术练习,不幸的是,因为你不能使用c++。基本上,您必须管理分配的一些开销,并跟踪已分配了多少内存,如果稍后需要调整它的大小。这就是c++标准库的亮点所在。

For your example, the following code allocates the memory and later resizes it:

对于您的示例,下面的代码分配内存,然后调整它的大小:

// initial size
int count = 100;
words *testWords = (words*) malloc(count * sizeof(words));
// resize the array
count = 76;
testWords = (words*) realloc(testWords, count* sizeof(words));

Keep in mind, in your example you are just allocating a pointer to a char and you still need to allocate the string itself and more importantly to free it at the end. So this code allocates 100 pointers to char and then resizes it to 76, but does not allocate the strings themselves.

记住,在您的示例中,您只是分配一个指向字符的指针,您仍然需要分配字符串本身,更重要的是在末尾释放它。这段代码为char分配了100个指针,然后将其调整为76,但是没有分配字符串本身。

I have a suspicion that you actually want to allocate the number of characters in a string which is very similar to the above, but change word to char.

我怀疑您实际上想要分配字符串中的字符数,这与上面的非常相似,但是要将word改为char。

EDIT: Also keep in mind it makes a lot of sense to create functions to perform common tasks and enforce consistency so you don't copy code everywhere. For example, you might have a) allocate the struct, b) assign values to the struct, and c) free the struct. So you might have:

编辑:还要记住,创建函数来执行常见任务并加强一致性是很有意义的,这样就不会到处复制代码。例如,您可能有a)分配结构体,b)分配结构体的值,c)释放结构体。所以你可能会有:

// Allocate a words struct
words* CreateWords(int size);
// Assign a value
void AssignWord(word* dest, char* str);
// Clear a words structs (and possibly internal storage)
void FreeWords(words* w);

EDIT: As far as resizing the structs, it is identical to resizing the char array. However the difference is if you make the struct array bigger, you should probably initialize the new array items to NULL. Likewise, if you make the struct array smaller, you need to cleanup before removing the items -- that is free items that have been allocated (and only the allocated items) before you resize the struct array. This is the primary reason I suggested creating helper functions to help manage this.

编辑:对于调整结构的大小,它与调整char数组的大小是相同的。但是,不同之处在于,如果您使struct数组更大,您可能应该将新数组项初始化为NULL。同样,如果使struct数组更小,则需要在删除项之前进行清理——这是在调整struct数组大小之前已分配的*项(仅包括已分配的项)。这是我建议创建帮助函数来帮助管理的主要原因。

// Resize words (must know original and new size if shrinking
// if you need to free internal storage first)
void ResizeWords(words* w, size_t oldsize, size_t newsize);

#4


3  

In C++, use a vector. It's like an array but you can easily add and remove elements and it will take care of allocating and deallocating memory for you.

在c++中,使用一个向量。它就像一个数组,但是您可以轻松地添加和删除元素,它将负责为您分配和释放内存。

I know the title of the question says C, but you tagged your question with C and C++...

我知道题目说的是C,但是你用C和c++标记了你的问题……

#5


3  

Another option for you is a linked list. You'll need to analyze how your program will use the data structure, if you don't need random access it could be faster than reallocating.

另一个选项是链表。您将需要分析您的程序将如何使用数据结构,如果不需要随机访问,它可能比重新分配要快。

#6


3  

Here is how I would do it in C++

这里是我如何用c++写的。

size_t size = 500;
char* dynamicAllocatedString = new char[ size ];

Use same principal for any struct or c++ class.

对于任何struct或c++类使用相同的主体。

#7


1  

Your code in the last update should not compile, much less run. You're passing &x to LoadData. &x has the type of **words, but LoadData expects words* . Of course it crashes when you call realloc on a pointer that's pointing into stack.

上次更新中的代码不应该编译,更不用说运行了。您将传递&x到LoadData。&x有**字的类型,但LoadData需要*字。当然,当您在指向堆栈的指针上调用realloc时,它会崩溃。

The way to fix it is to change LoadData to accept words** . Thi sway, you can actually modify the pointer in main(). For example, realloc call would look like

修复它的方法是更改LoadData以接受words**。因此可以修改main()中的指针。例如,realloc调用看起来是这样的

*x = (words*) realloc(*x, sizeof(words)*2);

It's the same principlae as in "num" being int* rather than int.

这和“num”中的原则是int*而不是int。

Besides this, you need to really figure out how the strings in words ere stored. Assigning a const string to char * (as in str2 = "marley\0") is permitted, but it's rarely the right solution, even in C.

除此之外,你还需要弄清楚单词中的字符串是如何存储的。允许为char *分配const字符串(如str2 =“marley\0”),但它很少是正确的解决方案,即使是在C中。

Another point: non need to have "marley\0" unless you really need two 0s at the end of string. Compiler adds 0 tho the end of every string literal.

另一点:不需要有“marley\0”,除非你真的需要两个0在字符串的末尾。编译器在每个字符串的末尾加0。

#8


1  

For the test code: if you want to modify a pointer in a function, you should pass a "pointer to pointer" to the function. Corrected code is as follows:

对于测试代码:如果要修改函数中的指针,应该向函数传递一个“指针指向指针”。更正后的代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

typedef struct
{
    char *str1;
    char *str2;
} words;

void LoadData(words**, int*);

main()
{
    words **x;
    int num;

    LoadData(x, &num);

    printf("%s %s\n", (*x[0]).str1, (*x[0]).str2);
    printf("%s %s\n", (*x[1]).str1, (*x[1]).str2);
}

void LoadData(words **x, int *num)
{
    *x = (words*) malloc(sizeof(words));

    (*x[0]).str1 = "johnnie\0";
    (*x[0]).str2 = "krapson\0";

    *x = (words*) realloc(*x, sizeof(words) * 2);
    (*x[1]).str1 = "bob\0";
    (*x[1]).str2 = "marley\0";

    *num = *num + 1;
}

#9


0  

If you want to grow the array dynamically, you should use malloc() to dynamically allocate some fixed amount of memory, and then use realloc() whenever you run out. A common technique is to use an exponential growth function such that you allocate some small fixed amount and then make the array grow by duplicating the allocated amount.

如果您想动态地扩展数组,您应该使用malloc()来动态地分配一定数量的内存,然后在耗尽时使用realloc()。一种常见的技术是使用指数增长函数,这样您就可以分配一些小的固定数量,然后通过复制分配的数量使数组增长。

Some example code would be:

一些示例代码是:

size = 64; i = 0;
x = malloc(sizeof(words)*size); /* enough space for 64 words */
while (read_words()) {
    if (++i > size) {
        size *= 2;
        x = realloc(sizeof(words) * size);
    }
}
/* done with x */
free(x);

#10


0  

Every coder need to simplify their code to make it easily understood....even for beginners.

每个编码器需要简化代码以使它容易理解....即使是初学者。

So array of structures using dynamically is easy, if you understand the concepts.

所以动态结构数组很简单,如果你理解这些概念的话。

// Dynamically sized array of structures

#include <stdio.h>
#include <stdlib.h>

struct book 
{
    char name[20];
    int p;
};              //Declaring book structure

int main () 
{
    int n, i;      

    struct book *b;     // Initializing pointer to a structure
    scanf ("%d\n", &n);

    b = (struct book *) calloc (n, sizeof (struct book));   //Creating memory for array of structures dynamically

    for (i = 0; i < n; i++)
    {
        scanf ("%s %d\n", (b + i)->name, &(b + i)->p);  //Getting values for array of structures (no error check)
    }          

    for (i = 0; i < n; i++)
    {
        printf ("%s %d\t", (b + i)->name, (b + i)->p);  //Printing values in array of structures
    }

    scanf ("%d\n", &n);     //Get array size to re-allocate    
    b = (struct book *) realloc (b, n * sizeof (struct book));  //change the size of an array using realloc function
    printf ("\n");

    for (i = 0; i < n; i++)
    {
        printf ("%s %d\t", (b + i)->name, (b + i)->p);  //Printing values in array of structures
    }

    return 0;
}   

#11


-2  

Check out malloc and realloc.

查看malloc和realloc。

#1


35  

You've tagged this as C++ as well as C.

您已经将它标记为c++和C。

If you're using C++ things are a lot easier. The standard template library has a template called vector which allows you to dynamically build up a list of objects.

如果你用的是c++,事情就简单多了。标准模板库有一个名为vector的模板,它允许您动态地构建对象列表。

#include <stdio.h>
#include <vector>

typedef std::vector<char*> words;

int main(int argc, char** argv) {

        words myWords;

        myWords.push_back("Hello");
        myWords.push_back("World");

        words::iterator iter;
        for (iter = myWords.begin(); iter != myWords.end(); ++iter) {
                printf("%s ", *iter);
        }

        return 0;
}

If you're using C things are a lot harder, yes malloc, realloc and free are the tools to help you. You might want to consider using a linked list data structure instead. These are generally easier to grow but don't facilitate random access as easily.

如果您正在使用C语言,那么事情就会变得更加困难,是的,malloc、realloc和free都是帮助您的工具。您可能需要考虑使用链表数据结构。这些通常都比较容易实现,但不方便随意访问。

#include <stdio.h>
#include <stdlib.h>

typedef struct s_words {
        char* str;
        struct s_words* next;
} words;

words* create_words(char* word) {
        words* newWords = malloc(sizeof(words));
        if (NULL != newWords){
                newWords->str = word;
                newWords->next = NULL;
        }
        return newWords;
}

void delete_words(words* oldWords) {
        if (NULL != oldWords->next) {
                delete_words(oldWords->next);
        }
        free(oldWords);
}

words* add_word(words* wordList, char* word) {
        words* newWords = create_words(word);
        if (NULL != newWords) {
                newWords->next = wordList;
        }
        return newWords;
}

int main(int argc, char** argv) {

        words* myWords = create_words("Hello");
        myWords = add_word(myWords, "World");

        words* iter;
        for (iter = myWords; NULL != iter; iter = iter->next) {
                printf("%s ", iter->str);
        }
        delete_words(myWords);
        return 0;
}

Yikes, sorry for the worlds longest answer. So WRT to the "don't want to use a linked list comment":

哎呀,对不起,世界上最长的答案。因此,WRT到“不要使用链表注释”:

#include <stdio.h>  
#include <stdlib.h>

typedef struct {
    char** words;
    size_t nWords;
    size_t size;
    size_t block_size;
} word_list;

word_list* create_word_list(size_t block_size) {
    word_list* pWordList = malloc(sizeof(word_list));
    if (NULL != pWordList) {
        pWordList->nWords = 0;
        pWordList->size = block_size;
        pWordList->block_size = block_size;
        pWordList->words = malloc(sizeof(char*)*block_size);
        if (NULL == pWordList->words) {
            free(pWordList);
            return NULL;    
        }
    }
    return pWordList;
}

void delete_word_list(word_list* pWordList) {
    free(pWordList->words);
    free(pWordList);
}

int add_word_to_word_list(word_list* pWordList, char* word) {
    size_t nWords = pWordList->nWords;
    if (nWords >= pWordList->size) {
        size_t newSize = pWordList->size + pWordList->block_size;
        void* newWords = realloc(pWordList->words, sizeof(char*)*newSize); 
        if (NULL == newWords) {
            return 0;
        } else {    
            pWordList->size = newSize;
            pWordList->words = (char**)newWords;
        }

    }

    pWordList->words[nWords] = word;
    ++pWordList->nWords;


    return 1;
}

char** word_list_start(word_list* pWordList) {
        return pWordList->words;
}

char** word_list_end(word_list* pWordList) {
        return &pWordList->words[pWordList->nWords];
}

int main(int argc, char** argv) {

        word_list* myWords = create_word_list(2);
        add_word_to_word_list(myWords, "Hello");
        add_word_to_word_list(myWords, "World");
        add_word_to_word_list(myWords, "Goodbye");

        char** iter;
        for (iter = word_list_start(myWords); iter != word_list_end(myWords); ++iter) {
                printf("%s ", *iter);
        }

        delete_word_list(myWords);

        return 0;
}

#2


11  

If you want to dynamically allocate arrays, you can use malloc from stdlib.h.

如果希望动态分配数组,可以使用stdlib.h中的malloc。

If you want to allocate an array of 100 elements using your words struct, try the following:

如果您想使用word struct分配一个包含100个元素的数组,请尝试以下操作:

words* array = (words*)malloc(sizeof(words) * 100);

The size of the memory that you want to allocate is passed into malloc and then it will return a pointer of type void (void*). In most cases you'll probably want to cast it to the pointer type you desire, which in this case is words*.

要分配的内存的大小被传递给malloc,然后它将返回一个类型为void (void*)的指针。在大多数情况下,您可能希望将它转换为您想要的指针类型,在本例中是words*。

The sizeof keyword is used here to find out the size of the words struct, then that size is multiplied by the number of elements you want to allocate.

这里使用sizeof关键字来查找单词struct的大小,然后将该大小乘以要分配的元素的数量。

Once you are done, be sure to use free() to free up the heap memory you used in order to prevent memory leaks:

完成后,请确保使用free()释放用于防止内存泄漏的堆内存:

free(array);

If you want to change the size of the allocated array, you can try to use realloc as others have mentioned, but keep in mind that if you do many reallocs you may end up fragmenting the memory. If you want to dynamically resize the array in order to keep a low memory footprint for your program, it may be better to not do too many reallocs.

如果您想更改已分配数组的大小,您可以尝试使用realloc,就像其他人提到的那样,但是请记住,如果您执行了许多reallocs,那么您可能最终导致内存碎片化。如果您想动态地调整数组的大小以保持程序的低内存占用,最好不要做太多的reallocs。

#3


5  

This looks like an academic exercise which unfortunately makes it harder since you can't use C++. Basically you have to manage some of the overhead for the allocation and keep track how much memory has been allocated if you need to resize it later. This is where the C++ standard library shines.

这看起来像是一个学术练习,不幸的是,因为你不能使用c++。基本上,您必须管理分配的一些开销,并跟踪已分配了多少内存,如果稍后需要调整它的大小。这就是c++标准库的亮点所在。

For your example, the following code allocates the memory and later resizes it:

对于您的示例,下面的代码分配内存,然后调整它的大小:

// initial size
int count = 100;
words *testWords = (words*) malloc(count * sizeof(words));
// resize the array
count = 76;
testWords = (words*) realloc(testWords, count* sizeof(words));

Keep in mind, in your example you are just allocating a pointer to a char and you still need to allocate the string itself and more importantly to free it at the end. So this code allocates 100 pointers to char and then resizes it to 76, but does not allocate the strings themselves.

记住,在您的示例中,您只是分配一个指向字符的指针,您仍然需要分配字符串本身,更重要的是在末尾释放它。这段代码为char分配了100个指针,然后将其调整为76,但是没有分配字符串本身。

I have a suspicion that you actually want to allocate the number of characters in a string which is very similar to the above, but change word to char.

我怀疑您实际上想要分配字符串中的字符数,这与上面的非常相似,但是要将word改为char。

EDIT: Also keep in mind it makes a lot of sense to create functions to perform common tasks and enforce consistency so you don't copy code everywhere. For example, you might have a) allocate the struct, b) assign values to the struct, and c) free the struct. So you might have:

编辑:还要记住,创建函数来执行常见任务并加强一致性是很有意义的,这样就不会到处复制代码。例如,您可能有a)分配结构体,b)分配结构体的值,c)释放结构体。所以你可能会有:

// Allocate a words struct
words* CreateWords(int size);
// Assign a value
void AssignWord(word* dest, char* str);
// Clear a words structs (and possibly internal storage)
void FreeWords(words* w);

EDIT: As far as resizing the structs, it is identical to resizing the char array. However the difference is if you make the struct array bigger, you should probably initialize the new array items to NULL. Likewise, if you make the struct array smaller, you need to cleanup before removing the items -- that is free items that have been allocated (and only the allocated items) before you resize the struct array. This is the primary reason I suggested creating helper functions to help manage this.

编辑:对于调整结构的大小,它与调整char数组的大小是相同的。但是,不同之处在于,如果您使struct数组更大,您可能应该将新数组项初始化为NULL。同样,如果使struct数组更小,则需要在删除项之前进行清理——这是在调整struct数组大小之前已分配的*项(仅包括已分配的项)。这是我建议创建帮助函数来帮助管理的主要原因。

// Resize words (must know original and new size if shrinking
// if you need to free internal storage first)
void ResizeWords(words* w, size_t oldsize, size_t newsize);

#4


3  

In C++, use a vector. It's like an array but you can easily add and remove elements and it will take care of allocating and deallocating memory for you.

在c++中,使用一个向量。它就像一个数组,但是您可以轻松地添加和删除元素,它将负责为您分配和释放内存。

I know the title of the question says C, but you tagged your question with C and C++...

我知道题目说的是C,但是你用C和c++标记了你的问题……

#5


3  

Another option for you is a linked list. You'll need to analyze how your program will use the data structure, if you don't need random access it could be faster than reallocating.

另一个选项是链表。您将需要分析您的程序将如何使用数据结构,如果不需要随机访问,它可能比重新分配要快。

#6


3  

Here is how I would do it in C++

这里是我如何用c++写的。

size_t size = 500;
char* dynamicAllocatedString = new char[ size ];

Use same principal for any struct or c++ class.

对于任何struct或c++类使用相同的主体。

#7


1  

Your code in the last update should not compile, much less run. You're passing &x to LoadData. &x has the type of **words, but LoadData expects words* . Of course it crashes when you call realloc on a pointer that's pointing into stack.

上次更新中的代码不应该编译,更不用说运行了。您将传递&x到LoadData。&x有**字的类型,但LoadData需要*字。当然,当您在指向堆栈的指针上调用realloc时,它会崩溃。

The way to fix it is to change LoadData to accept words** . Thi sway, you can actually modify the pointer in main(). For example, realloc call would look like

修复它的方法是更改LoadData以接受words**。因此可以修改main()中的指针。例如,realloc调用看起来是这样的

*x = (words*) realloc(*x, sizeof(words)*2);

It's the same principlae as in "num" being int* rather than int.

这和“num”中的原则是int*而不是int。

Besides this, you need to really figure out how the strings in words ere stored. Assigning a const string to char * (as in str2 = "marley\0") is permitted, but it's rarely the right solution, even in C.

除此之外,你还需要弄清楚单词中的字符串是如何存储的。允许为char *分配const字符串(如str2 =“marley\0”),但它很少是正确的解决方案,即使是在C中。

Another point: non need to have "marley\0" unless you really need two 0s at the end of string. Compiler adds 0 tho the end of every string literal.

另一点:不需要有“marley\0”,除非你真的需要两个0在字符串的末尾。编译器在每个字符串的末尾加0。

#8


1  

For the test code: if you want to modify a pointer in a function, you should pass a "pointer to pointer" to the function. Corrected code is as follows:

对于测试代码:如果要修改函数中的指针,应该向函数传递一个“指针指向指针”。更正后的代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

typedef struct
{
    char *str1;
    char *str2;
} words;

void LoadData(words**, int*);

main()
{
    words **x;
    int num;

    LoadData(x, &num);

    printf("%s %s\n", (*x[0]).str1, (*x[0]).str2);
    printf("%s %s\n", (*x[1]).str1, (*x[1]).str2);
}

void LoadData(words **x, int *num)
{
    *x = (words*) malloc(sizeof(words));

    (*x[0]).str1 = "johnnie\0";
    (*x[0]).str2 = "krapson\0";

    *x = (words*) realloc(*x, sizeof(words) * 2);
    (*x[1]).str1 = "bob\0";
    (*x[1]).str2 = "marley\0";

    *num = *num + 1;
}

#9


0  

If you want to grow the array dynamically, you should use malloc() to dynamically allocate some fixed amount of memory, and then use realloc() whenever you run out. A common technique is to use an exponential growth function such that you allocate some small fixed amount and then make the array grow by duplicating the allocated amount.

如果您想动态地扩展数组,您应该使用malloc()来动态地分配一定数量的内存,然后在耗尽时使用realloc()。一种常见的技术是使用指数增长函数,这样您就可以分配一些小的固定数量,然后通过复制分配的数量使数组增长。

Some example code would be:

一些示例代码是:

size = 64; i = 0;
x = malloc(sizeof(words)*size); /* enough space for 64 words */
while (read_words()) {
    if (++i > size) {
        size *= 2;
        x = realloc(sizeof(words) * size);
    }
}
/* done with x */
free(x);

#10


0  

Every coder need to simplify their code to make it easily understood....even for beginners.

每个编码器需要简化代码以使它容易理解....即使是初学者。

So array of structures using dynamically is easy, if you understand the concepts.

所以动态结构数组很简单,如果你理解这些概念的话。

// Dynamically sized array of structures

#include <stdio.h>
#include <stdlib.h>

struct book 
{
    char name[20];
    int p;
};              //Declaring book structure

int main () 
{
    int n, i;      

    struct book *b;     // Initializing pointer to a structure
    scanf ("%d\n", &n);

    b = (struct book *) calloc (n, sizeof (struct book));   //Creating memory for array of structures dynamically

    for (i = 0; i < n; i++)
    {
        scanf ("%s %d\n", (b + i)->name, &(b + i)->p);  //Getting values for array of structures (no error check)
    }          

    for (i = 0; i < n; i++)
    {
        printf ("%s %d\t", (b + i)->name, (b + i)->p);  //Printing values in array of structures
    }

    scanf ("%d\n", &n);     //Get array size to re-allocate    
    b = (struct book *) realloc (b, n * sizeof (struct book));  //change the size of an array using realloc function
    printf ("\n");

    for (i = 0; i < n; i++)
    {
        printf ("%s %d\t", (b + i)->name, (b + i)->p);  //Printing values in array of structures
    }

    return 0;
}   

#11


-2  

Check out malloc and realloc.

查看malloc和realloc。