给指针增加超大偏移量出现意外输出,为何程序未崩溃?
为什么给指针加超大偏移后程序没崩溃?
首先要明确:你这段代码里给指针加上超大值后访问内存的行为属于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
相关产品推荐
相关产品推荐

