从理论上迭代内存地址?

时间:2013-05-18 08:59:45

标签: c++ memory iteration memory-address

正如问题所示:

如果您遍历内存,或选择随机内存地址分配随机数据会发生什么?

当然有一些保护可以防止这种情况,但为了以防万一,我不打算试一试。

我知道这似乎是一个幼稚的问题,但这是出于好奇的名义!

3 个答案:

答案 0 :(得分:4)

如果您尝试访问未分配给您的进程的内存地址,或者您违反了访问控制(例如尝试写入标记为只读的地址),您很可能会触发陷阱(分段) Unix上的违规,Windows上的内存保护错误。)

如果将随机数据写入内存的某些可访问部分,则可能会损坏程序使用的数据结构,可能会覆盖堆栈的关键部分或堆的簿记数据。这将导致程序无法预测,并且可能会或可能不会导致陷阱。

答案 1 :(得分:3)

我真的要看操作系统。

在所有现代操作系统中,内存确实受到保护,因为只有应用程序实际可用的内存才能进行虚拟地址转换(您的应用程序可能与另一种不同类型的应用程序具有相同的虚拟地址,但使用不同的物理地址)。

访问未“映射”的内存(虚拟地址没有转换为物理地址)将导致“页面错误”,操作系统随后会检查内存是否确实存在(它可能已被换出到磁盘),如果没有提出某些内容,则操作失败,这通常会结束您的程序。

答案 2 :(得分:3)

我认为满足您对地址空间的好奇心的最佳方法是检查某些进程的内存映射。例如,如果您使用的是Linux,请尝试:

$ cat /proc/2480/maps 
08048000-08049000 r-xp 00000000 08:05 8669698         /tmp/test
08049000-0804a000 r--p 00000000 08:05 8669698         /tmp/test
0804a000-0804b000 rw-p 00001000 08:05 8669698         /tmp/test
f759f000-f75a0000 rw-p 00000000 00:00 0
f75a0000-f7740000 r-xp 00000000 08:05 4465182         /lib32/libc-2.15.so
f7740000-f7741000 ---p 001a0000 08:05 4465182         /lib32/libc-2.15.so
f7741000-f7743000 r--p 001a0000 08:05 4465182         /lib32/libc-2.15.so
f7743000-f7744000 rw-p 001a2000 08:05 4465182         /lib32/libc-2.15.so
f7744000-f7748000 rw-p 00000000 00:00 0
f775e000-f7760000 rw-p 00000000 00:00 0
f7760000-f7761000 r-xp 00000000 00:00 0               [vdso]
f7761000-f7781000 r-xp 00000000 08:05 4465203         /lib32/ld-2.15.so  
f7781000-f7782000 r--p 0001f000 08:05 4465203         /lib32/ld-2.15.so  
f7782000-f7783000 rw-p 00020000 08:05 4465203         /lib32/ld-2.15.so  
ffc67000-ffc88000 rw-p 00000000 00:00 0               [stack]

2480是您感兴趣的某个过程的PID(在我的情况下,我只是运行了一个测试程序)。

第一列和第二列是地址空间的范围;指针值基本上。这些范围称为“映射”,因为它们建立了一系列“映射”的地址空间,这意味着您可以读取,写入和/或执行它。 OS将每个映射设置为对应于一些存储器和/或文件。如果您的进程尝试读取,写入或执行任何不在这些范围之一的指针,程序将会出现段错误。请注意,指针值“0”没有映射 - 这就是操作系统保证取消引用NULL指针会使程序崩溃的方式。

对于这些范围内的任何指针值,会发生什么取决于该映射的内存保护(r是可读的,w是可写的,x是可执行的)以及映射的内容在那个地址。您会注意到我的程序本身(/tmp/test)被映射到地址空间;如果我从这些地区读到,我会阅读我的程序的代码和数据。其他范围映射在共享库中,最后一个映射是堆栈。

当然,这一切都假设您正在使用MMU在受内存保护的操作系统下运行程序; MMU是让操作系统设置这些具有不同意义的特定范围的原因。在没有MMU的CPU上,通过内存读取只会读取所有内存本身的物理内容。