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函数都能复现此问题。
错误原因
- 函数内存区域只读:编译后的函数代码会被加载到程序的只读内存段(如.text段),操作系统会保护这部分内存不允许写入。你通过
reinterpret_cast将函数指针转为int*后执行写入操作,本质是往只读内存地址写数据,直接触发访问违例错误。 - 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
相关产品推荐
相关产品推荐

