You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免内存同一位置重复写入?C语言词法扫描器问题

解决C语言词法扫描器Lexeme指向同一内存的问题

问题根源

你当前的实现中,所有Token的lexeme都指向同一块动态分配的内存区域,每次循环都会覆盖这块内存的内容,最终所有Token的lexeme自然都指向最后一次写入的字符。而直接使用&scanner->source[scanner->column]会得到从该位置开始的完整字符串(因为C字符串以'\0'结尾),不符合单字符lexeme的需求。

解决方案

1. 为每个Token的Lexeme单独分配内存

针对单字符场景,每次识别字符时,为当前Token的lexeme分配独立内存并复制字符内容:

// 假设token是已初始化的Token结构体指针
token->lexeme = malloc(2); // 1字节存字符,1字节存终止符'\0'
if (token->lexeme == NULL) {
    // 处理内存分配失败,比如返回错误或终止程序
    fprintf(stderr, "Memory allocation failed\n");
    exit(EXIT_FAILURE);
}
token->lexeme[0] = scanner->source[scanner->column];
token->lexeme[1] = '\0';

这样每个Token的lexeme都拥有独立的内存空间,后续循环的写入操作不会覆盖之前的内容。

2. 兼容多字符Lexeme的扩展方案

要支持关键字(如var、return)或标识符这类多字符lexeme,只需调整为记录起始位置→扫描结束位置→分配对应内存→复制子串的逻辑:

// 记录lexeme的起始列号
int start_col = scanner->column;

// 扫描直到lexeme结束(示例:匹配字母数字组成的标识符/关键字)
while (isalnum((unsigned char)scanner->source[scanner->column])) {
    scanner->column++;
}

// 计算lexeme长度并分配内存
int lexeme_len = scanner->column - start_col;
token->lexeme = malloc(lexeme_len + 1);
if (token->lexeme == NULL) {
    fprintf(stderr, "Memory allocation failed\n");
    exit(EXIT_FAILURE);
}

// 复制子串并添加终止符
strncpy(token->lexeme, &scanner->source[start_col], lexeme_len);
token->lexeme[lexeme_len] = '\0';

这个逻辑可以统一处理单字符和多字符lexeme,无需单独分支判断。

3. 内存管理注意事项

所有通过malloc分配的lexeme内存,在Token不再使用时必须逐个调用free(token->lexeme)释放,避免内存泄漏。如果你的扫描器会生成大量Token,可以考虑实现一个Token池或统一的内存回收机制,但对于小型扫描器,逐个释放已经足够。

内容的提问来源于stack exchange,提问作者AlphabetsAlphabets

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 02:23:13