我只是在寻找一种更好的方法来在 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) 作为“返回值”。
这看起来不错,除了:
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;
}
作为进一步的步骤,您可能希望将此逻辑分解为向量结构和操作它的函数。
正如所建议的,链表可能是另一种值得研究的数据结构,但前提是您不需要随机访问内容。