为什么我不能得到存储单元n中的内容?

时间:2014-05-24 14:45:07

标签: c++ pointers memory

我试图让对象位于地址32.所以,我写了这段代码:

char *cp = (char *)32;
cout<<*cp<<endl;

然而,程序崩溃,显示一个msg框读取“test.exe已停止工作”。我该如何解决这个问题?

3 个答案:

答案 0 :(得分:3)

正如this中提到的那样,c / c ++中的内存访问并不是狂野的西部,除非你在某些自定义操作系统/硬件上允许你做这些事情(你知道:)) ,你不应该尝试。

访问您之前未分配的任何地址可能会导致程序崩溃

因此,如果你想获得一块必须分配它的堆,你可以访问最小地址,例如在c ++中(也在ideone上):

#include <iostream>
using namespace std;

int main() {
    int *myC = new int(); // now I ask the OS to give me some heap space to store an int
    *myC = 123; // assign a value to it
    cout<< "Content "<< *myC << endl; // this will print 123
    cout<< "Adress "<< myC << endl;  // this will print the actual address that the OS gave for this variable 
    delete myC; // after you've used the memory allocated you have to release the memory
    return 0;
}

总而言之,操作系统透明地为我们管理这些分配,并且比在程序中的每个点记住您使用过的地址以及您没有使用过的地方要好得多。

答案 1 :(得分:3)

有很多方法可以考虑为什么你会得到你所看到的行为。

从语言的角度来看,C ++标准规定,如果访问任何与对象不对应的内存,则生成的程序具有未定义的行为。这意味着C ++对可能发生的事情完全没有限制。您可能能够读取或写入内存,但也可能会立即使程序崩溃。原则上,在嵌入式设备中,它可能会使计算机着火!因此,您的问题的一个答案是&#34;您访问的内存与对象没有对应关系,因此结果未定义,并且在您的计算机上它碰巧使程序崩溃。&#34;

从机器的角度来看,C ++的大多数实现都会将您的代码解释为&#34;创建指向字节32的指针,然后尝试取消引用它。&#34;在大多数操作系统上,操作系统和程序设置为将程序的内存分配到不同的段(代码,文本,堆栈,堆等),操作系统将终止尝试读取这些段之外的内存的任何程序。原因通常与虚拟内存有关。当程序运行时,操作系统为程序设置虚拟地址空间,并提供从虚拟地址(程序看到的内容)到物理地址(实际上在RAM中的内容)的映射。每当您尝试访问内存时,操作系统都会将您的查找从虚拟地址重新映射到某个物理地址。如果程序试图读取或写入不是OS映射的一部分的存储器地址,则OS不能分配该读取或写入物理存储器位置,因此它将程序终止避免摄入垃圾值或破坏其他记忆。

也就是说,在较旧的操作系统或嵌入式设备上,您绝对可以读取或写入任意内存位置。例如,如果您正在编程微控制器,则某些固定存储器地址可能与物理设备(灯,端口等)相对应。因此,对这些设备的地址进行类型转换是很常见的。到指针然后读取或写入指针。在没有虚拟内存的旧系统中,试图读取或写入垃圾内存的程序可能会破坏其他进程的内存,从而导致整个系统崩溃或导致严重的安全漏洞。

我不相信Windows中有一种机制可以读取物理内存,因为它是一种主要的安全风险(想象一下,如果病毒可以在您输入时从浏览器中读取进程内存密码!)我相信,我可以使用一些函数来读写进程内存,尽管系统安全管理器可能会阻止它们在导致安全问题的情况下工作。

希望这有帮助!

答案 2 :(得分:1)

第一个内存页面通常受到保护以捕获NULL访问错误。

希望你这样做是为了好奇,而不是在制作软件中。您可以使用Windows上的结构化异常处理或Linux上的信号来处理访问冲突。