我有三个C代码。在第一个代码c0.c中,整数指针(p)是动态分配的存储器,用于保存一个整数值。值325被分配给该指针变量(p)指向的内存。该指针的整数值存储在一个文件中。在不释放内存的情况下,该指针变量(p)被赋予NULL值。然后将整数值再次读入长变量(i),并为指针变量(p)分配该变量(i)的(int *)值。取消引用并打印时,它会输出值325.代码如下所示。
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *p = (int*)malloc(sizeof(int));
*p = 325;
FILE *F;
F = fopen("xxx", "w");
fprintf(F, "%ld", (long)p);
fclose(F);
p = NULL;
long i;
F = fopen("xxx", "r");
fscanf(F, "%ld", &i);
p = (int*)i;
fclose(F);
printf("value stored in read pointer = %d\n", *p);
return(0);
}
现在使用两个单独的文件c1.c和c2.c尝试相同的事情。在c1.c中,指针p被分配了存储器,值325被存储在它指向的存储器中。指针的整数值存储在文件中,扫描程序暂停程序执行。在c2.c中,读取指针的整数值并将其分配给另一个整数指针。取消引用此指针变量,并尝试打印该值。预计产量为325。因此,当c1.c被编译并运行并且暂停时,将运行c2.c的已编译可执行文件。它崩溃了。为什么呢?
c1.c和c2.c如下。
c1.c:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *p = (int*)malloc(sizeof(int));
*p = 325;
FILE *F;
F = fopen("xxx", "w");
fprintf(F, "%ld", (long)p);
fclose(F);
int j;
scanf("%d", &j); // To pause the program and run c2.c executable
return(0);
}
c2.c:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *p;
long i;
FILE *F;
F = fopen("xxx", "r");
fscanf(F, "%ld", &i);
p = (int*)i;
fclose(F);
printf("value stored in read pointer = %d\n", *p);
return(0);
}
答案 0 :(得分:5)
所有现代现代操作系统都使用虚拟内存。在虚拟内存中,每个进程都有自己的虚拟地址空间。虚拟地址空间分为两个不同的区域:用户空间和系统(或内核)空间。
所有流程的系统空间都相同。但是,它不能从用户模式写入,并且大多数地址在用户模式下不可读或不可执行。
用户模式地址空间(您可以处理的部分)对于每个进程都是唯一的。一个进程中的地址1000通常与另一个进程中的地址1000不同。
通常可以创建可由多个进程访问的共享内存区域。但是,这些可以映射到不同的虚拟地址。在共享内存区域中,地址为1000的更改 在一个过程中,可以在另一个过程中的地址2000000处看到。
当您读取由一个进程写入的地址值并尝试在另一个进程中访问它们时,这些地址无法访问并且正在崩溃。由于无法访问,尚未在进程的虚拟地址空间中创建这些地址。即使它们被创建,它们也不会与其他进程中的内存相同。
答案 1 :(得分:1)
您的操作系统使用virtual address space process isolation。