C词法分析器pos指针值意外重置Bug求助
C词法分析器中标识符识别函数的pos指针异常问题
问题背景
在实现C语言词法分析器的reconhece_id函数时,出现指针变量pos行为异常:首次递增pos指向的值后,第二次执行增量操作时,pos指向的值意外重置为0,导致词法分析器工作异常。
相关代码
TInfoAtomo reconhece_id(char* buffer, int *pos) { int init_id = *pos; TInfoAtomo infoAtomo; infoAtomo.atomo = ERRO; if(islower(buffer[*pos])) { *pos++; goto q1; } return infoAtomo; q1: if(islower(buffer[*pos])||isdigit(buffer[*pos])) { *pos++; goto q1; } if(isupper(buffer[*pos])) return infoAtomo; strncpy(infoAtomo.atributo_ID, buffer + init_id, (*pos) - init_id); infoAtomo.atributo_ID[(*pos) - init_id] = '\x0'; infoAtomo.atomo = IDENTIFICADOR; return infoAtomo; }
调试过程(GDB输出)
reconhece_id (buffer=0x406490 "abc 10.0 f 20.0\n30.0 \n40.0", pos=0x7fffffffdb78) at src/TInfoAtomo.c:98 98 int init_id = *pos; (gdb) p pos $1 = (int *) 0x7fffffffdb78 (gdb) p *pos $2 = 0 (gdb) n 100 infoAtomo.atomo = ERRO; (gdb) p init_id $3 = 0 (gdb) n 102 if(islower(buffer[*pos])) (gdb) 104 *pos++; (gdb) 105 goto q1; (gdb) p *pos $4 = 1 (gdb) n 110 if(islower(buffer[*pos])||isdigit(buffer[*pos])) (gdb) p *pos $5 = 1 (gdb) p buffer[*pos] $6 = 98 'b' (gdb) n 112 *pos++; (gdb) 113 goto q1; (gdb) p *pos $7 = 0
原因分析
核心问题是运算符优先级错误:在C语言中,++运算符的优先级高于*(解引用)运算符,因此*pos++等价于*(pos++)——它先将指针pos本身向后移动一个int的长度(而非递增指针指向的数值),再对移动后的指针进行解引用。
第一次执行*pos++时,移动后的指针恰好指向原pos相邻的栈内存地址,该地址的临时值为1,所以调试时看到*pos为1;第二次执行*pos++时,指针继续移动到无效栈地址,该地址的值为0,就出现了*pos被重置为0的现象。
解决方案
需要明确表达“递增指针指向的数值”的意图,将所有*pos++替换为以下两种写法之一:
- 用括号改变优先级:
(*pos)++ - 直接前置递增:
++(*pos)
修改后的核心代码片段:
if(islower(buffer[*pos])) { (*pos)++; goto q1; } // ... q1: if(islower(buffer[*pos])||isdigit(buffer[*pos])) { (*pos)++; goto q1; }
这样就能保证每次操作都是递增pos指针指向的数值,而非移动指针本身,从而避免内存越界和数值异常问题。
内容的提问来源于stack exchange,提问作者Matheus Farias
相关产品推荐
相关产品推荐

