【问题标题】:Dynamic string array structure in CC中的动态字符串数组结构
【发布时间】:2016-12-08 22:04:27
【问题描述】:

我是 C 新手,我想创建一个动态数组来存储字符串。我为它写了下面的代码,但它没有用。数组元素包含一些 ASCII 字符而不是字符串。 我希望historyArray[0] 的值为"foo"。我该怎么做?

typedef struct {
    char *historyCommand;
    int usedSize;
    int maximumSize;
} HistoryArray;

void CreateHistoryArray(HistoryArray *HistoryArray) {
    HistoryArray->historyCommand = (char *) malloc(sizeof(char) * MAX_LEN);
    HistoryArray->usedSize = 0;
    HistoryArray->maximumSize = INITIAL_SIZE;
}

void ExpandHistoryArray(HistoryArray *HistoryArray, int newSize) {
    int *newArray = (char *) malloc(sizeof(char) * newSize);
    memcpy(newArray, HistoryArray->historyCommand, sizeof(char) * HistoryArray->maximumSize);
    free(HistoryArray->historyCommand);
    HistoryArray->historyCommand = newArray;
    HistoryArray->maximumSize = newSize;
}

void AddHistoryValue(HistoryArray *HistoryArray, char historyCommand[]) {
    strcpy(HistoryArray->historyCommand[HistoryArray->usedSize], historyCommand);

    HistoryArray->usedSize++;

    if (HistoryArray->usedSize == HistoryArray->maximumSize) {
        ExpandHistoryArray(HistoryArray, HistoryArray->maximumSize * 2);
    }
}

void freeHistoryArray(HistoryArray *a) {
    free(a->historyCommand);
    a->historyCommand = NULL;
    a->usedSize = 0;
    a->maximumSize = 2;
}


HistoryArray historyArray;

【问题讨论】:

  • 请提供minimal reproducible example。您如何调用以及调用哪些函数? “我希望 historyArray[0] 的值为“foo”。这没有意义。historyArray[0] 不是 char 数组。请在描述中更准确。请使用适当的缩进格式化代码可读。
  • char *HistoryArray 不是一个字符串数组,它是一个字符数组,它只是一个字符串。
  • BTW, malloc + memcpy + freerealloc 相同。
  • 编译器不会警告您strcpy() 行中的参数类型错误吗?

标签: c arrays dynamic struct


【解决方案1】:

您的代码中存在许多问题。

  1. char *historyCommand 是指向单个字符串的指针,而不是字符串数组。对于指向字符串数组的指针,您应该使用char **historyCommand

  2. 当您创建HistoryArray 时,您不需要为各个字符串分配空间。您可以在每次添加到数组时分配适当的空间量,使用要添加的字符串的长度。

  3. 您应该使用realloc() 而不是调用malloc()memcpy()free()。这样做的好处是有时它可以简单地扩展它已经分配的内存,因此不需要复制。

  4. 释放HistoryArray 时,需要释放所有字符串。你不应该释放historyCommand,因为你设置了maximumSize = 2,而其他函数假设这意味着那里有2个项目的空间,如果你将historyCommand设置为NULL,这不是真的。所以你应该将它的大小调整为maximumSize 以与其余代码保持一致。

这是新代码:

typedef struct {
    char **historyCommand;
    int usedSize;
    int maximumSize;
} HistoryArray;

void CreateHistoryArray(HistoryArray *HistoryArray) {
    HistoryArray->historyCommand = malloc(INITIAL_SIZE * sizeof(char *));
    HistoryArray->usedSize = 0;
    HistoryArray->maximumSize = INITIAL_SIZE;
}

void ExpandHistoryArray(HistoryArray *HistoryArray, int newSize) {
    HistoryArray->historyCommand = realloc(HistoryArray->historyCommand, newSize * sizeof(char *));
    HistoryArray->maximumSize = newSize;
}

void AddHistoryValue(HistoryArray *HistoryArray, char historyCommand[]) {
    historyCommand[HistoryArray->usedSize] = malloc(strlen(historyCommand) + 1);
    strcpy(HistoryArray->historyCommand[HistoryArray->usedSize], historyCommand);

    HistoryArray->usedSize++;

    if (HistoryArray->usedSize == HistoryArray->maximumSize) {
        ExpandHistoryArray(HistoryArray, HistoryArray->maximumSize * 2);
    }
}

void freeHistoryArray(HistoryArray *a) {
    for (int i = 0; i < a->usedSize; i++) {
        free a->historyCommand[i];
    }
    a->usedSize = 0;
    a->maximumSize = 2;
    a->historyCommand = realloc(a->historyCommand, a->maximumSize * sizeof(char *));
}

HistoryArray historyArray;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-11
    • 2017-08-27
    • 2016-03-06
    • 2020-02-09
    • 2012-10-11
    • 1970-01-01
    相关资源
    最近更新 更多