C++ 在C+中更改越界指针的解引用是否安全+;?

C++ 在C+中更改越界指针的解引用是否安全+;?,c++,pointers,memory,shared-memory,C++,Pointers,Memory,Shared Memory,假设我有一个坏指针,我递增它以查看下一个内存位置中的内容。我的代码运行良好,没有任何错误或问题。我只是打印出这些内存位置的内容。我在屏幕上看到了输出,其中一些内存位置的值为0,其他一些包含一些大的负数或正数,似乎是按模式排列的。但是,如果我试图更改或覆盖这些内存位置的内容,该怎么办?它们代表什么?哪些类型的数据可能存储在这些内存位置,如果更改足够多的内存位置,是否可能破坏操作系统 #include <iostream> using std::cout; using std

假设我有一个坏指针,我递增它以查看下一个内存位置中的内容。我的代码运行良好,没有任何错误或问题。我只是打印出这些内存位置的内容。我在屏幕上看到了输出,其中一些内存位置的值为0,其他一些包含一些大的负数或正数,似乎是按模式排列的。但是,如果我试图更改或覆盖这些内存位置的内容,该怎么办?它们代表什么?哪些类型的数据可能存储在这些内存位置,如果更改足够多的内存位置,是否可能破坏操作系统

  #include <iostream>
  using std::cout;
  using std::endl;
  int main() {
    int num1 = 5;
    int* bad_ptr = &num1;
    cout << "Address of num1: " << &num1 << endl;
    cout << "Dereference bad pointer: " << *bad_ptr << endl;

    // The bad pointer acesses 500 memory addresses
    for (int i = 0; i < 500; i++) {
      bad_ptr++;
      cout << "Dereference bad pointer: " << *bad_ptr << endl;
      // What if I try to change it?
      // *bad_ptr = 1;
    }
    return 0;
  }
#包括
使用std::cout;
使用std::endl;
int main(){
int num1=5;
int*bad_ptr=&num1;

coutTL;DR这是未定义的行为,不应该这样做

更实际的答案是,这在很大程度上取决于地址。在本例中,您使用的是位于上的
int
的地址。如果继续递增指针,则基本上是在查看堆栈内存。如果要对调用
malloc()的指针执行相同的操作
您将看到整个堆中的内存

关于通过更改值来影响操作系统稳定性的问题,除非您在内核空间中,否则答案是否定的。但是,如果您在内核空间中运行的驱动程序中执行此操作,则可能导致操作系统崩溃


这个答案肯定不是详尽的,而且令人难以置信地摇摆不定,因为你的问题有很多细微差别,所以我建议你在开始时参考TL;DR。我建议你搜索并阅读基本的计算机架构。

TL;DR这是未定义的行为,不应该这样做

更实际的答案是,这在很大程度上取决于地址。在本例中,您使用的是位于上的
int
的地址。如果继续递增指针,则基本上是在查看堆栈内存。如果要对调用
malloc()的指针执行相同的操作
您将看到整个堆中的内存

关于通过更改值来影响操作系统稳定性的问题,除非您在内核空间中,否则答案是否定的。但是,如果您在内核空间中运行的驱动程序中执行此操作,则可能导致操作系统崩溃


这个答案肯定不是详尽无遗的,而且令人难以置信地摇摆不定,因为您的问题有很多细微差别,所以我建议您在开始时参考TL;DR。我建议您搜索并阅读基本的计算机体系结构。

参考错误的指针是未定义的。但是,您所做的可能不会只是偶然地造成错误

在大多数C++实现中,NUM1将被分配到堆栈上。在大多数计算机系统中,堆栈都会向较低的地址增长。递增指针正在将自己移回堆栈中调用函数的堆栈帧(即,所有在主操作之前进行初始化的那些帧)。 如果将循环限制设置得足够大,最终会发现问题


但是,如果我试图更改或覆盖这些内存位置的内容,该怎么办?它们代表什么?这些内存位置中可能存储哪些类型的数据?如果更改足够多的内存位置,是否可能破坏操作系统

  #include <iostream>
  using std::cout;
  using std::endl;
  int main() {
    int num1 = 5;
    int* bad_ptr = &num1;
    cout << "Address of num1: " << &num1 << endl;
    cout << "Dereference bad pointer: " << *bad_ptr << endl;

    // The bad pointer acesses 500 memory addresses
    for (int i = 0; i < 500; i++) {
      bad_ptr++;
      cout << "Dereference bad pointer: " << *bad_ptr << endl;
      // What if I try to change it?
      // *bad_ptr = 1;
    }
    return 0;
  }
这都是特定于系统的,但一般来说,调用函数时,会在堆栈上创建调用帧。调用帧包括函数的参数、函数调用返回后要执行的下一条指令的地址以及保存的寄存器。调用帧包括还原调用函数所需的所有信息当被调用函数返回时

通常有一个指向当前调用帧(帧指针)的硬件寄存器

在调用帧之间,堆栈包含当前正在执行的函数的局部变量

当函数返回时,它使用帧指针寄存器定位调用帧。然后恢复调用帧中的数据(包括以前保存的帧指针值),并继续执行调用函数

如果您要覆盖指针的内容,这可能就是您正在处理的问题。您的调用函数可能会看到其变量发生更改。您的程序可能会崩溃。任何情况都可能发生

有些函数会像你那样破坏调用框架,这需要确切地知道调用框架的布局和寄存器的用法

例如,有一个公共库函数alloca()与malloc()类似,只是它在堆栈上分配内存,以便在当前函数返回时自动释放内存。实现alloca需要搞乱调用它的函数的状态。这需要了解调用帧的结构


如果你弄乱了这些值,你就不会破坏操作系统。你只会伤害你自己。

引用错误的指针是未定义的。但是,你所做的事情很可能不会因为意外而导致错误

在大多数C++实现中,NUM1将被分配到堆栈上。在大多数计算机系统中,堆栈都会向较低的地址增长。递增指针正在将自己移回堆栈中调用函数的堆栈帧(即,所有在主操作之前进行初始化的那些帧)。 如果将循环限制设置得足够大,最终会发现问题


但是,如果我试图更改或覆盖这些内存位置的内容,该怎么办?它们代表什么?这些内存位置中可能存储哪些类型的数据?如果这些内存位置中有足够的内存位置将被删除,是否有可能破坏操作系统