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

32位ARM平台nt98566上strlen返回值if判断异常问题求助

问题:strlen返回值与整数比较出现异常的排查与解决

代码场景

char stack_protect[1000] = {0};
char temp[100] = { 0 };
memset(&temp, 1, 110);
int len = strlen(temp);

printf("test strlen of temp %d \n", len);
if (len > 100)
{
    // 预期执行此处,但实际进入else分支
}
else
{
    // 实际执行分支
}

char stack_protect2[1000] = {0};

异常现象

strlen(temp)返回值为110,打印输出也确认这一点,但if(len > 100)的判断结果为false。

运行环境:Linux系统、32位ARM架构、SOC为nt98566。

已完成的测试

  • 将len赋值给新的int变量len1后,if(len1 > 100)判断结果为true:
    char temp[100] = { 0 };
    memset(&temp, 1, 110);
    int len = strlen(temp);
    
    int len1 = len;
    
    if (len1 > 100) // 结果为TRUE
    
  • 查看len的内存字节:0x6e, 0x00, 0x00, 0x00(对应十进制110,小端存储)
  • 在hisiv300 SOC上执行相同逻辑,len=110时if(len>100)判断结果为true。

原因分析

  1. 栈越界引发未定义行为:temp是100字节数组,但memset(&temp, 1, 110)越界写入10字节,直接破坏栈上相邻内存区域。栈帧被破坏后,编译器的优化逻辑失去可靠依据,导致len的存储或比较逻辑出现异常。
  2. 类型转换与编译器优化叠加问题:strlen返回值类型为size_t(32位ARM下是unsigned int),你将其赋值给signed int类型的len。nt98566对应的编译器(大概率是特定版本GCC)的激进优化下,可能直接用strlen的无符号返回值参与比较,而非读取len的实际存储值;或者栈越界导致编译器无法正确追踪len的取值,触发不符合预期的优化判断。

解决方案

  1. 修复栈越界(核心):立即修正memset的写入长度,确保不超过数组大小:
    memset(temp, 1, sizeof(temp)); // 写入长度改为数组实际大小100
    
    栈越界属于未定义行为,所有后续异常都可能由此引发,必须优先修复。
  2. 统一变量类型:将len的类型改为size_t,避免无符号/有符号类型转换陷阱:
    size_t len = strlen(temp);
    if (len > 100) {
        // 逻辑代码
    }
    
  3. 显式类型转换(临时兼容):如果必须用int存储,比较时显式转换为size_t:
    int len = (int)strlen(temp);
    if ((size_t)len > 100) {
        // 逻辑代码
    }
    
  4. 临时关闭优化排查:添加编译选项-O0关闭所有优化,验证是否为优化导致的异常,但最终仍需以修复栈越界为根本解决办法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 14:29:58