C++中内存的播放

C++中内存的播放,c++,pointers,memory,segmentation-fault,C++,Pointers,Memory,Segmentation Fault,这有点奇怪……我写了一段很短的代码,为一个整数分配一些内存,保存一个值,并打印出保存它的内存地址: #include <iostream> using namespace std; int main (void) { int * b = new int; *b = 12345; cout << " -> *b = " << *b << endl; cout << " ->

这有点奇怪……我写了一段很短的代码,为一个整数分配一些内存,保存一个值,并打印出保存它的内存地址:

#include <iostream>

using namespace std;

int main (void) {

    int * b = new int;

    *b = 12345;

    cout << "   -> *b = " << *b << endl;
    cout << "   ->  b = " <<  b << endl;

    return 0;
}
据我所知,没有理由认为这个值在内存中仍然不冷,因为我没有主动删除它-因此,为了好玩,我尝试运行以下程序:

-> *b = 123456
->  b = 0x7f9429c04bf0
#include <iostream>

using namespace std;

int main (void) {

    int * b = reinterpret_cast <int*> (0x7f9429c04bf0);

    cout << "   -> *b = " << *b << endl;
    cout << "   ->  b = " <<  b << endl;

    return 0;
}
这会抛出一个segfault-有人知道为什么不允许这样做吗?我的意思是…这显然不是一个好主意,我也没有计划在实践中使用它,但我很好奇。 干杯
Jack

每个进程都有自己的虚拟内存空间,与其他进程分开。当进程终止时,操作系统将回收其内存

它抛出segfault的原因是,操作系统不满意您的程序试图访问不属于它的内存


拥有受保护内存背后的整个想法是隔离进程,这样它们就不会相互干扰内存,导致不愉快的事情发生。即使你可以访问随机的内存位置,你也不会在那里找到任何有趣的东西。它基本上与访问未初始化指针时得到的内容相同

每个进程都有自己的虚拟内存空间,独立于其他进程。当进程终止时,操作系统将回收其内存

它抛出segfault的原因是,操作系统不满意您的程序试图访问不属于它的内存


拥有受保护内存背后的整个想法是隔离进程,这样它们就不会相互干扰内存,导致不愉快的事情发生。即使你可以访问随机的内存位置,你也不会在那里找到任何有趣的东西。它基本上与访问未初始化指针时得到的内容相同

即使你同时运行两个程序,我也希望你会因此而被踢,而不是得到正确的答案。你认为我应该能够通过猜测地址来访问另一个程序数据,这意味着很可怕,尽管如果你想了解一些历史,曾经有一个名为核心战争的游戏,其中包括这样做,试图让彼此崩溃


我想真正的答案是,它有未定义的行为,你应该庆幸它没有仅仅内爆。

即使你同时运行两个程序,我也希望你因此而被踢,而不是得到正确的答案。你认为我应该能够通过猜测地址来访问另一个程序数据,这意味着很可怕,尽管如果你想了解一些历史,曾经有一个名为核心战争的游戏,其中包括这样做,试图让彼此崩溃


<> P>我想真正的答案是,这是一种不确定的行为,你应该感激它并没有崩溃。

< P>大多数现代C++平台都是用底层OS提供的虚拟内存来工作的。虚拟内存并不是一种你似乎相信的微不足道的物理存储形式。虚拟内存只是一个假想的概念性存储,只在进程运行时存在。每次访问进程地址空间时,它都会模拟类似内存的行为

您对0x7f9429c04bf0的访问不是对物理内存地址的访问,而是对进程虚拟地址空间的访问,它将重定向到您无法预测的某个物理位置

当进程结束时,它的虚拟内存将永远消失。不管怎么说,它是模拟的,在某种意义上是假的。当您启动另一个进程时,它将获得自己的虚拟内存,而该内存与旧进程没有任何连接。在新流程中,访问0x7f9429c04bf0将导致无法预测的其他物理位置,或者,在您的情况下,如果0x7f9429c04bf0甚至无效,则会导致崩溃


期望你的价值仍然在记忆中令人寒心是相当天真的。事实上,你的价值从来没有真正地适合于任何一种令人寒心的内存。

< P>大多数现代C++平台都是由底层OS提供的虚拟内存工作的。虚拟内存并不是一种你似乎相信的微不足道的物理存储形式。虚拟内存只是一个假想的概念性存储,只在进程运行时存在。每次访问进程地址空间时,它都会模拟类似内存的行为

您对0x7f9429c04bf0的访问不是对物理内存地址的访问,而是对进程虚拟地址空间的访问,它将重定向到您无法预测的某个物理位置

当进程结束时,它的虚拟内存将永远消失。不管怎么说,它是模拟的,在某种意义上是假的。当您启动另一个进程时,它将获得自己的虚拟内存,而该内存与旧进程没有任何连接。在新流程中,访问0x7f9429c04bf0将导致无法预测的其他物理位置,或者,在您的情况下,如果0x7f9429c04bf0甚至无效,则会导致崩溃

期待
就你的价值而言,在记忆中依然令人心寒是相当幼稚的。事实上,您的值从未真正存在于任何适合任何类型的内存中。

每个进程在其自己的地址空间中运行,传递给reinterpret_cast的地址ur应该可以在当前进程的地址空间中访问,而不是因为第二个进程具有不同的地址空间布局。而且,即使是第一个程序的每次迭代都会给出u个不同的地址,这就是ASLRAddress空间布局随机化的全部要点,即随机化每个新实例上进程内存的关键部分。拥有静态地址,就像ASLR之前的情况一样,会造成严重破坏,从而容易利用易受攻击的程序

了解有关ASLR的更多信息: 虚拟内存:

每个进程都在自己的地址空间中运行,传递给reinterpret_cast的地址ur应该可以在当前进程的地址空间中访问,因为第二个进程的地址空间布局不同。而且,即使是第一个程序的每次迭代都会给出u个不同的地址,这就是ASLRAddress空间布局随机化的全部要点,即随机化每个新实例上进程内存的关键部分。拥有静态地址,就像ASLR之前的情况一样,会造成严重破坏,从而容易利用易受攻击的程序

了解有关ASLR的更多信息: 虚拟内存:

你使用的是C++的新操作符,但是你的问题被标记了C。请使用正确的标签。你正在进入未定义的行为。内存段在另一个运行中可能无效。随机寻址是一种内存保护机制。@dandan78的答案是正确的。你可以阅读更多关于这个的信息。你正在使用C++的新操作符,但是你的问题被标记了C。请使用正确的标签。你正在进入未定义的行为。内存部分在另一个运行中可能无效。随机寻址是一种内存保护机制。@dandan78的答案是正确的。你可以阅读关于了解更多关于这方面的内容。好的,这是由于操作系统处于保护状态。这是有道理的,我只是好奇是否有办法将这个问题作为memoryOk的一个小实验来解决,所以它是由操作系统的保护性引起的。这是有道理的,我只是好奇是否有办法将这个问题作为一个关于记忆的小实验来解决