假设我执行以下操作
int *p = 1;
printf("%d", *p);
我遇到了段错误。现在,据我所知,这个内存位置1位于我程序的地址空间中。为什么读取此内存位置时会出现问题?
答案 0 :(得分:4)
你的指针没有指向任何有效的东西。您所做的就是将值1
分配给指向int的指针,但1
不是有效的内存位置。
获取指针值的唯一有效方法是获取变量的地址或调用分配函数:
int a;
int * p1 = &a; // OK
int * p2 = malloc(sizeof(int)); // also OK
*p1 = 2;
*p2 = 3;
至于“为什么会出现问题”:就语言而言,如果取消引用无效指针,则会有未定义的行为,因此任何事情都可能发生 - 这实际上是唯一明智的方法来指定语言,如果你不想引入任何限制,C就是易于实现。
实际上,现代操作系统通常会有一个聪明的虚拟内存管理器,需要在需要时根据需要请求内存,如果地址1
的内存不在已提交的页面上,那么实际上从操作系统中获取错误。如果你在一些实际地址附近尝试指针值,你可能不会收到错误(直到你超越页面边界,可能)。
答案 1 :(得分:3)
要正确回答这个问题,将取决于许多因素。但是,很可能地址0x00000001(第0页)未映射和/或读取保护。
通常,出于某种原因,用户应用程序不允许页面0范围内的地址。即使在内核空间(取决于处理器),第0页中的地址也经常受到保护,并且要求页面都被映射并启用访问。
编辑: 另一个可能的原因是它可能是segfaulting是整数访问没有对齐。
答案 2 :(得分:2)
您的操作系统不允许您访问不属于您的程序的内存位置。它可以在内核模式下工作......
答案 3 :(得分:2)
不,地址1不在您程序的地址空间中。您正在尝试访问您不拥有的细分受众群并收到细分错误。
答案 4 :(得分:1)
您正在尝试打印1,而不是内存位置。 1不是有效的内存位置。要打印实际的内存位置,请执行以下操作:
printf("%p", p);
请注意icktoofay指出的%p。