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

unsigned long变量引发段错误之谜:为何size_t会导致系统崩溃?

其他进制转十进制C程序的段错误原因解析
#include<stdio.h>
#include<string.h>
#include<stdbool.h>
#include<math.h>
#include<stdlib.h>

float other_to_decimal(char *n, unsigned int base)
{
    float out = 0;
    size_t point_idx = 0,len = strlen(n);

    // 判断输入是否为负数
    bool input_is_negative = (n[0] == '-') ? true : false;

    // 查找小数点的下标
    while (point_idx != len && n[point_idx] != '.')
        point_idx++;

    // 判断是否存在小数部分
    bool frac_part_exists = (point_idx == len || point_idx == len - 1) ? false : true;

    // 转换整数部分
    const size_t end = input_is_negative ? 1 : 0;
    int power = 0;
    for (int i = point_idx - 1; i >= end; i--, power++)
        out += n[i] <= '9' ? (n[i] - '0') * pow(base, power) : (n[i] - 'A' + 10) * pow(base, power);
    

    // 转换小数部分
    if(frac_part_exists)
    {
        power = -1;
        for (size_t i = point_idx + 1; i < len; i++,power--)
            out += n[i] <= '9' ? (n[i] - '0') * pow(base, power) : (n[i] - 'A' + 10) * pow(base, power);
    }

    out *= input_is_negative ? -1 : 1;

    return out;
}

int main(int argc, char const *argv[])
{
    printf("%f\n", other_to_decimal("1101.01", 2)); // 预期输出13.25

    return 0;
}

注:Linux环境编译需添加-lm参数链接数学库


问题核心

这段代码原本会触发段错误,将第23行的const size_t end改为int end后程序恢复正常。明明end仅取值0或1,均在size_t(底层为unsigned long)的支持范围内,且仅参与比较操作,为何会引发崩溃?


原因解析

问题出在有符号与无符号整数的隐式类型转换上:

在C语言中,当有符号整数(int类型的i)和无符号整数(size_t类型的end)进行比较时,有符号整数会被强制转换为无符号整数类型。以示例中的非负输入为例:

  1. 循环从point_idx-1(即3)开始递减,直到i变为-1。
  2. 此时执行i >= end比较时,i=-1会被转换为无符号整数,对应一个极大的正数(比如64位系统下为18446744073709551615),远大于end=0。
  3. 循环不会终止,i继续递减(作为有符号数会更小,但转成无符号数始终是极大值),导致访问数组n的下标越界,触发段错误。

当把end改为int类型后,i >= end是两个有符号整数的比较,i=-1时-1 >= 0不成立,循环正常终止,不会出现越界访问。


额外建议

  • 循环变量的类型尽量保持统一,避免有符号与无符号类型混用引发的隐式转换问题。
  • 处理字符串下标时,若涉及负数边界判断,建议使用有符号整数类型,或显式进行类型转换确保逻辑正确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 11:35:24