C 如果打印此内存位置的内容,为什么会出现分段错误

C 如果打印此内存位置的内容,为什么会出现分段错误,c,memory,pointers,C,Memory,Pointers,假设我做下面的事情 int*p=1; printf(“%d”,*p); 我犯了一个错误。现在,据我所知,这个内存位置1在我程序的地址空间中。为什么读取此内存位置时会出现问题 您正在尝试打印1,而不是内存位置。1不是有效的内存位置。要打印实际内存位置,请执行以下操作: printf("%p", p); 请注意icktoofay指出的%p。您的操作系统不允许您访问不属于程序的内存位置。它可以在内核模式下工作,但是…您的指针没有指向任何有效的东西。您只需将值1分配给指向int的指针,但1不是有效

假设我做下面的事情

int*p=1;
printf(“%d”,*p);


我犯了一个错误。现在,据我所知,这个内存位置1在我程序的地址空间中。为什么读取此内存位置时会出现问题

您正在尝试打印1,而不是内存位置。1不是有效的内存位置。要打印实际内存位置,请执行以下操作:

printf("%p", p);

请注意icktoofay指出的%p。

您的操作系统不允许您访问不属于程序的内存位置。它可以在内核模式下工作,但是…

您的指针没有指向任何有效的东西。您只需将值
1
分配给指向int的指针,但
1
不是有效的内存位置

获取指针值的唯一有效方法是获取变量地址或调用分配函数:

int a;
int * p1 = &a; // OK
int * p2 = malloc(sizeof(int));  // also OK

*p1 = 2;
*p2 = 3;
至于“为什么会有问题”:就语言而言,如果你去引用一个无效的指针,你就会有未定义的行为,所以任何事情都有可能发生——如果你不想引入任何任意的限制,这确实是指定语言的唯一明智的方法,而C语言就是为了易于实现


实际上,现代操作系统通常会有一个聪明的虚拟内存管理器,它需要在需要时请求内存,如果地址
1
处的内存还不在提交页面上,那么实际上操作系统会出错。如果在某个实际地址附近尝试指针值,则可能不会出现错误(可能在超出页面边界之前)。

否,地址1不在程序的地址空间中。您正在尝试访问一个您不拥有的段,并收到段错误。

正确回答此问题将取决于许多因素。但是,地址0x00000001(第0页)很可能没有映射和/或读保护

通常,出于某种原因,用户应用程序不允许使用第0页范围内的地址。即使在内核空间中(取决于处理器),页面0中的地址通常也会受到保护,并且需要对页面进行映射并启用访问

编辑:
另一个可能的原因是,可能是整数访问未对齐。

我认为指针的正确格式规范是
%p
,而不是
%d
。否。我没有试图打印内存位置。我确实在尝试打印存储在该内存位置的内容。我认为他实际上在尝试输出地址1处的
int
。我认为每个进程都有自己的虚拟地址空间。所以从0x0开始,所有空间都是我进程的,我应该能够访问它?@AnkurVj:所有虚拟空间都是你的,但你仍然需要先分配它才能成为有效位置。假设我声明一个整数并打印它的地址。该位置是真正的物理内存位置吗?@AnkurVj:它是一个逻辑地址,是与系统一起分配的。+1用于提及安全操作系统上甚至不允许映射页0(它可能导致对内核的攻击)。
int a;
int * p1 = &a; // OK
int * p2 = malloc(sizeof(int));  // also OK

*p1 = 2;
*p2 = 3;