如果打印此内存位置的内容,为什么会出现分段错误
假设我执行以下操作 <代码>
int *p = 1;
printf("%d", *p);
我遇到了段错误。现在,据我了解,这个内存位置 1 位于我的程序的地址空间中。为什么读取这个内存位置会出现问题?
Suppose I do the following
int *p = 1; printf("%d", *p);
I get a segfault. Now, as I understand it, this memory location 1 is in the address space of my program. Why should there be a problem in reading this memory location ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您的指针没有指向任何有效的内容。您所做的就是将值
1
分配给一个指向 int 的指针,但1
不是有效的内存位置。获取指针值的唯一有效方法是获取变量的地址或调用分配函数:
至于“为什么会出现问题”:就语言而言,如果取消引用无效指针,你有未定义的行为,所以任何事情都有可能发生——如果你不想引入任何任意的限制,这确实是指定语言的唯一明智的方法,而 C 就是为了易于实现。
实际上,现代操作系统通常会有一个聪明的虚拟内存管理器,它需要在需要时请求内存,并且如果地址
1
处的内存尚未位于已提交的页面上,您实际上会从操作系统收到错误。如果您尝试在某个实际地址附近使用指针值,您可能不会收到错误(也许直到您超出页面边界)。Your pointer doesn't point to anything valid. All you do is assign the value
1
to a pointer-to-int, but1
isn't a valid memory location.The only valid way to obtain an pointer value is either take the address-of a variable or call an allocation function:
As for "why there should be a problem": As far as the language is concerned, if you dereference an invalid pointer, you have undefined behaviour, so anything can happen -- this is really the only sensible way to specify the language if you don't want to introduce any arbitrary restrictions, and C is all about being easy-to-implement.
Practically, modern operating systems will usually have a clever virtual memory manager that needs to request memory when and as needed, and if the memory at address
1
isn't on a committed page yet, you'll actually get an error from the OS. If you try a pointer value near some actual address, you might not get an error (until you overstep the page boundary, perhaps).正确回答这个问题实际上取决于许多因素。然而,地址 0x00000001(第 0 页)很可能没有被映射和/或读保护。
通常,由于某种原因,用户应用程序不允许使用第 0 页范围内的地址。即使在内核空间中(取决于处理器),页 0 中的地址通常也受到保护,并且要求该页既被映射又能够访问。
编辑:
另一个可能的原因是整数访问未对齐,从而可能导致段错误。
To answer this properly will really depend upon a number of factors. However, it is quite likely that the address 0x00000001 (page 0) is not mapped and/or read protected.
Typically, addresses in the page 0 range are disallowed from a user application for one reason or another. Even in kernel space (depending upon the processor), addresses in page 0 are often protected and require that the page be both mapped and access enabled.
EDIT:
Another possible reason is that it could be segfaulting is that integer access is not aligned.
您的操作系统不会让您访问不属于您的程序的内存位置。不过它可以在内核模式下工作......
Your operating system won't let you access memory locations that don't belong to your program. It would work on kernel mode though...
不,地址 1 不在您的程序的地址空间中。您正在尝试访问不属于您的段并收到分段错误。
No, address 1 is not in the address space of your program. You are trying to access a segment you do not own and receive segmentation fault.
您正在尝试打印 1,而不是内存位置。 1 不是有效的内存位置。要打印实际的内存位置,请执行以下操作:
注意 icktoofay 指出的 %p。
You're trying to print 1, not the memory location. 1 isn't a valid memory location. To print the actual memory location do:
Note the %p as icktoofay pointed out.