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

C++通过指针访问struct成员的程序崩溃及内存操作问题咨询

问题1:std::cout崩溃而printf正常运行的原因

你修改值的代码存在内存越界写入问题,属于C++标准定义的未定义行为:

  • *Adress拿到的是IntPtr的值,也就是new int[2]返回的数组首地址,偏移sizeof(int)后刚好是数组第二个元素IntPtr[1]的地址
  • 你将该地址强制转为long long int*后解引用写入789,而64位环境下long long占8字节,int仅占4字节,相当于你除了修改IntPtr[1]的4字节外,还把紧跟在该元素后方的4字节内存给覆盖改写了。

printf正常运行只是巧合:你覆盖的那4字节内存刚好没有被printf的执行逻辑用到,而std::cout的内部实现(比如内部缓冲区指针、类成员数据、虚函数表等)刚好存放在被你覆盖的内存区域,调用cout时访问被破坏的内存直接触发崩溃。这不是printf更安全,只是未定义行为下的不同表现而已,换编译环境、编译参数都可能出现相反的结果。
如果你把代码里的long long int*改成int*再操作,cout和printf都会正常运行。

问题2:是否可以通过该方式删除、重分配IntPtr成员

仅在你当前的实验环境(64位系统、编译器生成标准布局struct)下可以正常运行,原理如下:

  1. 你定义的obj属于C++标准规定的标准布局类,类对象的地址和第一个非静态成员的地址完全相同,因此你将&MyStruct强转为long long*解引用后拿到的确实就是IntPtr成员的值
  2. 64位环境下指针长度和long long长度一致,因此你可以通过*Adress直接修改IntPtr的指向,哪怕IntPtr被声明为private也能绕开编译期的访问检查。

但要特别注意:这完全是依赖平台和编译器实现的未定义行为,换32位环境、或者struct里加了虚函数、调整了成员顺序的情况下,该写法都会直接出错,绝对不能用于生产代码。另外记得每次替换IntPtr指向的内存前,必须先delete[]原来的地址,否则会出现内存泄漏。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 14:45:03