如何在 C 中创建一个包含静态数组的动态数组?

How to create a dynamic array that holds static arrays in C?

我的程序解析代码,当它解析代码时,我需要根据我计划的信息跟踪每 x 行(可能每 10 行左右)它经历的每个关键字的实例数稍后使用 gnuplot 创建直方图,但这并不重要。

所以有 13 个关键字,我可以很容易地用一个 0 数组来计算它们,其中每个索引代表一个关键字,每当我找到一个关键字时,我都会将它的索引增加 1。好吧简单

int keywordcount[13]={0};

问题是我需要每 10 行创建一个新的 keywordcount,而且我不知道该文件有多少代码行。所以这告诉我我应该有一个 keywordcount 数组的动态数组。

如何在 C 中声明这个动态数组数组以及如何向其中添加 keywordcount 数组?我仍然对 C 中的多维数组感到困惑。我不知道是否应该将其声明为指针数组或什么,而且我不知道如何为它分配一个新的 keywordcount 数组当创建 keywordcount returns 的函数时,它不会消失。如果有什么不清楚的地方,请告诉我。

假设将创建多少 keywordcount。假设您几乎确定将创建其中的 10 个。

您可以动态地声明一个 10 行 13 列的二维数组。

现在 keywordcount[0] 将是第一个 keywordcount 数组(大小为 13)的索引,依此类推。

现在,如果在实际操作中您发现需要 10 个以上的关键字计数数组,您可以使用 realloc() 动态增加二维数组的大小。


PS:一个好的技巧是每次需要增加二维数组的大小时,将其按行增加一倍(而不是每次增加一行,这样就可以避免重定位) ,在某些情况下可能会损害性能)。

您可以使用malloc()calloc() 来创建静态数组的动态数组。例如,这将 keywordcount_arr 定义为指向 13 int 数组的指针(这里为 max_lines 这样的数组分配了足够的内存):

size_t max_lines = 10;
int (*keywordcount_arr)[13] = calloc(max_lines, sizeof *keywordcount_arr);

这里如果使用typedef可能会使代码更容易阅读和编写:

typedef int KW_Count[13];

/* ... */

KW_Count *keywordcount_arr = calloc(max_lines, sizeof *keywordcount_arr);

您可以使用二维数组索引对分配的内存进行索引:

for (size_t i = 0; i < 13; i++) {
    keywordcount_arr[0][i] = i;
}

或者,如果必须将现有数组存储在动态数组中,则可以使用memcpy()。如果动态数组需要增长,可以使用realloc()。并且 realloc() 可以再次用于 trim 动态分配到最终大小:

max_lines *= 2;
KW_Count *temp = realloc(keywordcount_arr,
                         sizeof *keywordcount_arr * max_lines);

这是一个示例程序:

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

#define NUM_KEYWORDS  13

typedef int KW_Count[NUM_KEYWORDS];

int main(void)
{
    size_t max_lines = 10;
    size_t num_lines = 0;
    KW_Count *keywordcount_arr = calloc(max_lines, sizeof *keywordcount_arr);
    if (keywordcount_arr == NULL) {
        perror("Allocation failure");
        /* Handle error... perhaps: */
        exit(EXIT_FAILURE);
    }

    /* Store keyword counts directly in keywordcount_arr[] */
    ++num_lines;
    for (size_t i = 0; i < NUM_KEYWORDS; i++) {
        keywordcount_arr[0][i] = i;
    }

    /* Or use memcpy() if an existing array must be stored */
    ++num_lines;
    KW_Count keywordcount = { 0, 2, 0, 0, 3, 1, 0, 0, 0, 1, 2, 0, 1 };
    memcpy(keywordcount_arr[1],
           keywordcount,
           sizeof *keywordcount * NUM_KEYWORDS);

    /* Use realloc() to grow the dynamic array as needed */
    max_lines *= 2;
    KW_Count *temp = realloc(keywordcount_arr,
                             sizeof *keywordcount_arr * max_lines);
    if (temp == NULL) {
        perror("Unable to reallocate");
        /* Handle error */
    } else {
        keywordcount_arr = temp;
    }

    /* Use realloc() to trim the dynamic array to final size */
    temp = realloc(keywordcount_arr, sizeof *keywordcount_arr * num_lines);
    if (temp == NULL) {
        perror("Unable to reallocate");
        /* Handle error */
    } else {
        keywordcount_arr = temp;
    }

    /* Display array contents */
    for (size_t i = 0; i < num_lines; i++) {
        for (size_t j = 0; j < NUM_KEYWORDS; j++) {
            printf("%5d", keywordcount_arr[i][j]);
        }
        putchar('\n');
    }

    /* Cleanup */
    free(keywordcount_arr);

    return 0;
}

程序输出:

    0    1    2    3    4    5    6    7    8    9   10   11   12
    0    2    0    0    3    1    0    0    0    1    2    0    1

不要触及二维数组、数组的数组、指针数组、指向数组的指针或任何此类废话。

将静态大小的数组包装在 struct.

typedef struct
{
  int keyword_count[13];
} fragment_info;

拥有一个 fragment_info 的动态数组,就像创建任何其他动态数组一样:

fragment_info* infos = malloc(initial_capacity * sizeof(*infos));
....
fragment_info* new_infos = realloc(infos, new_capacity * sizeof(*new_infos));

现在,如果您想要存储有关您的 10 行片段的附加信息,您自然有一个存放它的地方。只需将更多字段添加到 struct.