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

给指针增加超大偏移量出现意外输出,为何程序未崩溃?

为什么给指针加超大偏移后程序没崩溃?

首先要明确:你这段代码里给指针加上超大值后访问内存的行为属于C++标准定义的未定义行为——标准没有规定这种操作必须让程序崩溃,它的结果是完全不可预测的,"没崩溃"只是其中一种可能的表现。

具体拆解几个关键点:

  • 指针地址能正常输出的原因:指针本质就是一个存储内存地址的变量,对它做算术运算(比如newPtr += 1293893847)只是按照指针指向类型的字节数做偏移计算(这里是int类型,所以实际地址偏移是1293893847 * sizeof(int)字节),这个计算过程本身是合法的,只要结果能放进当前系统的指针存储空间(比如32位系统是4字节,64位是8字节),就能正常输出这个地址值——哪怕这个地址根本不属于你的程序进程。

  • 没崩溃也没得到有效值的原因:

    • 现代操作系统会给每个进程分配独立的虚拟地址空间,其中大部分地址是未被使用的,但不是所有无效地址都会触发段错误(崩溃)。如果你的指针恰好指向了一块被标记为"可读"但没有有效数据的内存区域(比如某些系统保留的内存页、或者进程地址空间里的空闲区域),读取这个地址时只会得到随机的垃圾值,而不会触发崩溃。
    • 只有当你访问的地址对应的虚拟内存页完全没有被映射到物理内存,或者被标记为不可访问时,操作系统才会触发段错误让程序崩溃——但这种情况不是必然发生的。
  • 重要提醒:永远不要依赖未定义行为的结果,它在不同编译器、操作系统、甚至同一程序的不同运行实例中都可能有完全不同的表现,今天没崩溃不代表下次不会,也不代表其他环境下不会。

你的测试代码:

#include <iostream>
using namespace std;

int main(){
// *pointer arithmetic

    int arr[] = {1, 2, 3, 4, 5};
    cout << arr << endl; // this prints an address

    int *newPtr = arr; // hence this means pointer has address of first element of the array
    cout << "Allocation of the array is as follows: " << endl;
    for (int i = 0; i < sizeof(arr) / sizeof(int); i++)
    {
        cout << newPtr << endl;
        newPtr++; // pointer shifts to next element of the array
    }
    newPtr += 1293893847;
    cout << "Address of random pointer is " << newPtr << endl;
    cout << "Value of random pointer is " << *newPtr << endl;

    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 22:13:25