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

reinterpret_cast<int*>转换void函数指针后写入触发内存访问违规

C++内存访问错误问题解答

问题描述

运行以下C++代码时触发内存访问错误:

void* Newnumber;
int* ptr;
Newnumber = &dbCircle;
ptr = reinterpret_cast<int*>(Newnumber);
        
*ptr = 1; //此处为何触发内存错误?

dbCircle(x, y, RADIUS); //Void function(int, int, int);

代码可正常编译,但运行时抛出异常:

Unhandled exception at program.exe: 0xC0000005: Access violation writing location 0x004e9e20

意图是通过修改指向void函数dbCircle的指针值,让函数返回1,但实际触发内存错误,任意接收3个int参数的void函数都能复现此问题。

错误原因

  1. 函数内存区域只读:编译后的函数代码会被加载到程序的只读内存段(如.text段),操作系统会保护这部分内存不允许写入。你通过reinterpret_cast将函数指针转为int*后执行写入操作,本质是往只读内存地址写数据,直接触发访问违例错误。
  2. void函数无法强制返回值:函数的返回类型是编译期确定的,void函数的调用约定(栈帧处理、返回值传递逻辑)和返回int的函数完全不同。即便能修改函数内存,调用方也不会去读取返回值的存储位置(比如x86架构下的eax寄存器),强行修改只会破坏原有逻辑,甚至导致程序崩溃。

正确解决方案

如果需要让原函数具备返回值,有两种可行方式:

  • 修改原函数定义:将dbCircle的返回类型从void改为int,并在函数体内添加return 1;语句。
  • 封装包装函数:如果无法修改原函数,可新增一个包装函数来实现需求:
int dbCircleWrapper(int x, int y, int radius) {
    dbCircle(x, y, radius);
    return 1;
}

之后调用dbCircleWrapper即可获取返回值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 00:50:29