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

2023-11-29

我知道如何创建具有预定义大小的结构数组。但是,有没有办法创建动态结构数组,使数组变得更大?

例如:

    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.
    }

这可能吗?


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

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

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

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


不过我已经取得了一些进展:

    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?

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

    x=NULL;

然后如果我尝试打印 x 我会得到一个错误,这正是我想要的。那么 free 函数是否不起作用,至少在我的编译器上是这样?我正在使用DevC?


谢谢,我现在明白了,因为:

FirstName 是一个指向 char 数组的指针,该数组没有被 malloc 分配,只有指针被分配,并且在调用 free 后,它不会擦除内存,它只是将其标记为在堆上可用以结束稍后写。 - 马特·史密斯

Update

我正在尝试模块化并将结构数组的创建放入函数中,但似乎没有任何效果。我正在尝试一些非常简单的事情,但我不知道还能做什么。它与以前一样,只是另一个函数 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;
    }//

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


您已将其标记为 C++ 和 C。

如果您使用 C++,事情会容易得多。标准模板库有一个名为“向量”的模板,它允许您动态构建对象列表。

#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;
}

如果您使用 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;
}

哎呀,抱歉世界上最长的答案。因此,请注意“不想使用链接列表注释”:

#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;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何创建动态大小的结构数组? 的相关文章