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

C语言中void指针两种取值方式的差异与段错误原因解析

两种写法的本质差异

先明确调用时的关键细节:你调用函数时传入的(void*)40是把整数40直接当作指针值传递,而非传递一个指向存储着40的内存地址的指针。


原写法触发段错误的原因

原代码:

unsigned int roll_no = *(unsigned int*)(key);

这里的key是void*类型,存储的数值是40。你把它强转成unsigned int*后解引用,相当于试图访问内存地址0x28(40的十六进制)。这个地址属于操作系统保留或无效内存空间,程序无权限读写,因此触发段错误。

修改后写法能运行的逻辑

修改后的代码:

unsigned int roll_no = *(unsigned int*)(&key);

这里的&key取的是函数参数key本身在栈上的内存地址。key是一个void*变量,里面存储着你传入的40。把&key强转成unsigned int*再解引用,本质是把key这个指针变量里的数值(40)当作unsigned int读取出来——多数系统中void*和unsigned int的字节长度一致(比如32位系统均为4字节),因此能正确拿到目标roll_no值,不会触发段错误。


额外提醒:这种写法的隐患

虽然当前运行正常,但*(unsigned int*)(&key)依赖void*与unsigned int的字节长度匹配,在64位系统搭配32位int的架构下会出问题。更规范的写法有两种:

  1. 直接把key强转为unsigned int:
    unsigned int roll_no = (unsigned int)key;
    
  2. 调用时传递真正的指针:
    unsigned int target_roll = 40;
    check_student_by_roll_number(john, &target_roll);
    
    此时原写法的解引用逻辑就能正常工作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 09:42:49