我应该如何在 C 函数内部动态分配内存?

问题描述 投票:0回答:1

我只是在寻找一种更好的方法来在 C 中动态分配“数组”。我习惯了 C++、Rust 和 Python,在这些语言中你可以只使用向量或列表,并且非常感谢一些反馈。

我编写了一个词法分析器来标记给定的输入(例如文本文件)。此外,我需要一个函数来自动处理下一个标记并收集数组中的所有标记,并得出以下结果:

Token* Lexer_Run(Lexer* lexer, int* destination_size)
{
    int i = 0, size = 128;
    Token* destination = (Token*)malloc(size * sizeof(Token));
    if (destination == NULL)
        die("Memory allocation failed!");

    Token token = Lexer_Advance(lexer);

    while (token.type != TOKEN_EOF)
    {
        if (i >= size - 1)
        {
            size *= 2;
            destination = (Token*)realloc(destination, size * sizeof(Token));
            if (destination == NULL)
                die("Memory allocation failed!");
        }

        destination[i] = token;
        i++;

        token = Lexer_Advance(lexer);
    }

    destination = (Token*)realloc(destination, i * sizeof(Token));
    if (destination == NULL)
        die("Memory allocation failed!");
    *destination_size = i;

    return destination;
}

这可行,但也许有更好的方法来实现这一点?对于这样一个简单的任务来说,这看起来太复杂了,但也许这只是 C...而且我不喜欢这样的事实:我本质上必须滥用函数的参数 (destination_size) 作为“返回值”。

arrays c malloc
1个回答
0
投票

这看起来不错,除了:

  • 不要投射
    malloc
    realloc
    的结果。
  • realloc
    的结果分配给不同的指针,这样如果失败就不会丢失原始指针。
  • 处理数组大小时,使用
    size_t
    而不是
    int
Token* Lexer_Run(Lexer* lexer, size_t* destination_size)
{
    size_t i = 0, size = 128;
    Token* destination = malloc(size * sizeof(*destination));
    if (destination == NULL)
        die("Memory allocation failed!");

    Token token = Lexer_Advance(lexer);

    while (token.type != TOKEN_EOF)
    {
        if (i >= size - 1)
        {
            size *= 2;
            Token* temp = realloc(destination, size * sizeof(Token));
            if (destination == NULL)
                die("Memory allocation failed!");

            destination = temp;
        }

        destination[i] = token;
        i++;

        token = Lexer_Advance(lexer);
    }

    Token* temp = realloc(destination, i * sizeof(Token));
    if (destination == NULL)
        die("Memory allocation failed!");
    destination = temp;
    *destination_size = i;

    return destination;
}

作为进一步的步骤,您可能希望将此逻辑分解为向量结构和操作它的函数。

正如所建议的,链表可能是另一种值得研究的数据结构,但前提是您不需要随机访问内容。

© www.soinside.com 2019 - 2024. All rights reserved.