我在Windows 8.1上编写了这个非常简单的程序,并使用Mingw的gcc编译它。我用" test.exe>运行它t.txt"和" test.exe> t1.txt"并且输出不同(即使它使用虚拟地址)。它运行了一段时间然后它崩溃了。我决定测试这个,因为我正在读一本关于操作系统的书。
是否在阅读其他节目'记忆?那不应该发生吗?我可能误解了一些事情......
#include <stdio.h>
int main(int argc, char *argv[]){
int r = 0;
int p[4] = {1,5,4,3};
for(r=0; p[r]!=1111111111111111; r++){
p[2] = p[r];
printf("%d\n", p[2]);
}
return 0;
}
谢谢。
答案 0 :(得分:4)
SadSeven,我假设您是故意读取数组的末尾。你所看到的不是其他程序内存,它是程序内存中未初始化的内存。
每个程序都在它自己的虚拟内存空间内运行,os的虚拟内存管理器负责处理这个问题。你不能从你的程序访问另一个程序内存(除非你们都使用共享内存,但你必须故意这样做)
答案 1 :(得分:3)
您尚未初始化p[3]
以外的任何内容。当您尝试访问尚未使用数据进行初始化的地址时,C语言无法保证会发生什么。您可能会看到一堆垃圾,但垃圾不是由您编写的程序定义的。它可以是任何东西。
崩溃前访问的地址仍然属于当前进程,它只是堆栈和堆之间存在的单元化内存。
由于分段错误,进程可能会崩溃,当进程尝试访问不属于它的内存时会发生分段错误。这将是它试图在自己的内存之外访问的时候。
答案 2 :(得分:2)
您看到的输出来自于读取自己的内存。当它到达未分配给该进程的内存时,它会崩溃。
修改强>
为了使计算机病毒更加困难,每次运行starting address of a program will be different时都会遇到问题。因此,如果多次运行它,您应该期望不同的输出。 In Windows, the adress space layout is not randomized by all programs
您的程序超出了本地(自动)变量,这意味着它会向上走过stack frame(s)。堆栈帧包含局部变量,函数参数,保存的寄存器,函数调用的返回地址以及指向前一个堆栈帧结尾的指针。如果变量都具有相同的值,则任何差异都将由存储器地址不同来解释。可能还有其他原因我不知道,因为我不是Windows中内存布局的专家。
答案 3 :(得分:0)
在您的代码中,for
循环是错误的。
for(r=0; p[r]!=1111111111111111; r++)
它尝试从4
r
的值开始访问超出范围的内存。结果是undefined behaviour。
在r
为1997
之前,它可能正常运行,可能会在r
值4
时崩溃,它可能会在r
开始播放您播放列表中的歌曲}值2015
,甚至。 r
值3
后无法保证此行为。
答案 4 :(得分:0)
每个进程在其单独的4GB虚拟地址空间内运行,尝试越界读取将不会从另一个进程的内存中读取。它将从自己的地址空间读取垃圾。现在,您一直在询问为什么输出不同,好吧,ASLR随机化可执行文件的关键部分,从而在进程实例中给出不同的入口点和堆栈地址,因此即使是同一个运行多次的进程也会有所不同切入点
在http://en.wikipedia.org/wiki/Address_space_layout_randomization了解ASLR 阅读有关虚拟内存的信息: http://en.wikipedia.org/wiki/Virtual_memory