一般指针问题[重复]

Posted

技术标签:

【中文标题】一般指针问题[重复]【英文标题】:General Pointer Questions [duplicate] 【发布时间】:2014-06-26 12:27:42 【问题描述】:

为什么我可以增加指针以读取超过分配变量的长度,而操作系统不会阻止我?当然,既然它是为整数留出 4 个字节,它应该知道它不应该允许任何指针经过这 4 个字节?

事实上,当我增加一个指针超过分配的变量字节时,我到底在读什么/那些相邻的内存位置?而且由于每个程序都应该有自己的“地址空间”,我不能在没有段错误的情况下在那个“地址空间”内做任何我想做的事情吗?如果每个程序都有自己的“地址空间”,应该不可能读取属于其他程序的内存吧?

【问题讨论】:

然后使用内存管理框架,如 .NET 或 Java。 C 不是为此而构建的。 这对 SO 来说不是一个好问题,很可能会被关闭。但幸运的是,我昨天在我的博客上回答了你的问题。 ericlippert.com/2014/05/07/why-does-my-code-not-crash 顺便说一句,您的错误在于“肯定是因为它是预留四个字节的那个”......它不是预留的操作系统四个字节。操作系统留出 4000 字节 并且 malloc 决定使用其中的四个作为整数。我经常注意到“肯定”这个词表明错误在哪里。 另请参阅有关相关情况的此问题:访问不再有效的内存:***.com/questions/6441218/… 【参考方案1】:

我注意到这个问题是我昨天博客的主题。见http://ericlippert.com/2014/05/07/why-does-my-code-not-crash

为什么我可以增加指针以读取超过分配变量的长度,而操作系统不会阻止我?

出于同样的原因,操作系统不会让您成为火腿三明治!没有人将火腿三明治功能写入操作系统,因此不会发生这种行为。未实现的功能未实现。阻止您这样做不是您正在使用的操作系统的功能。

当然,既然它是为整数留出 4 个字节,它应该知道它不应该允许任何指针超过这 4 个字节?

不。操作系统通常将 地址空间 放在称为 pages 的 4KB 块中。

事实上,当我增加一个指针超过分配的变量字节时,我到底在读什么?那些相邻的内存位置?

是的。它们是相邻的虚拟内存位置。

由于每个程序都应该有自己的“地址空间”,我不能在没有段错误的情况下在那个“地址空间”内做任何我想做的事情吗?

没有。您可以在地址空间中对已虚拟分配的地址执行任何操作。请注意,许多操作系统允许您对页面施加额外的限制,例如“此页面可以被读取但不能写入或执行”。在这些情况下,读取不会导致错误,但写入会。

如果每个程序都有自己的“地址空间”,应该不可能读取属于其他程序的内存吧?

这并非不可能,但通常是故意。在许多操作系统中,两个进程都可以同时将磁盘上文件的同一页映射到虚拟内存中,从而共享内存。

在前虚拟内存时代,Windows 3 等操作系统允许两个进程相互写入内存没有问题,但几十年来并非如此。

【讨论】:

【参考方案2】:

编译器可以执行此操作,但它选择不执行此操作,因为如果您对每次内存访问都执行此操作,运行时开销会造成严重的性能损失。

一些编译器带有一个选项来启用此检查,您可以在调试时使用该选项。

Eric Lippert 的评论回答了您的第二段。

【讨论】:

以上是关于一般指针问题[重复]的主要内容,如果未能解决你的问题,请参考以下文章

算法学习——双指针算法(最长连续不重复子序列)

多数之和问题

多数之和问题

指向指针数组和指针数组的指针之间的区别[重复]

删除空指针[重复]

悬空指针的含义[重复]