C 一般指针问题

C 一般指针问题,c,pointers,C,Pointers,为什么我可以增加指针来读取已分配变量的长度,而操作系统却不阻止我?当然,因为它是为整数留出4个字节的,所以它应该知道它不应该允许任何指针超过这4个字节 事实上,当我将指针递增超过变量的分配字节时,这些相邻的内存位置究竟在读什么?既然每个程序都应该有自己的“地址空间”,我就不能在这个“地址空间”内做任何我想做的事情而不出错吗?如果每个程序都有自己的“地址空间”,那么读取属于其他程序的内存应该是不可能的,对吧?编译器可以这样做,但它选择不这样做,因为如果对每个内存访问都这样做,则运行时开销会带来严重

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

事实上,当我将指针递增超过变量的分配字节时,这些相邻的内存位置究竟在读什么?既然每个程序都应该有自己的“地址空间”,我就不能在这个“地址空间”内做任何我想做的事情而不出错吗?如果每个程序都有自己的“地址空间”,那么读取属于其他程序的内存应该是不可能的,对吧?

编译器可以这样做,但它选择不这样做,因为如果对每个内存访问都这样做,则运行时开销会带来严重的性能损失

某些编译器提供了一个选项来启用此检查,您可以在调试时使用此选项


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

我注意到这个问题是我昨天博客的主题。看

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

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

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

没有。操作系统通常在称为页的4KB块中留出地址空间

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

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

既然每个程序都应该有自己的“地址空间”,我就不能在这个“地址空间”内做任何我想做的事情而不出错吗

不可以。您可以在地址空间中对已实际分配的地址执行任何操作。请注意,许多操作系统允许您在页面上设置附加约束,例如“此页面可以读取,但不能写入或执行”。在这些情况下,读取不会导致故障,但写入会导致故障

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

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


回到虚拟内存时代以前,像Windows 3这样的操作系统允许两个进程相互写入内存没有问题,但几十年来都不是这样。

使用内存管理框架,如.NET或Java。C不是为此而构建的。这对SO来说不是一个好问题,很可能会被关闭。但幸运的是,我昨天在博客上回答了你的问题。顺便说一句,您的错误出现在语句“肯定是因为它留出了四个字节”。。。并不是操作系统留出了四个字节。操作系统留出了4000个字节,malloc决定将其中的4个字节用于一个整数。我经常注意到“肯定”一词表示错误在哪里。另请参见有关相关情况的问题:访问不再有效的内存: