据我了解,只要程序试图访问未经授权的内存,就会引发段错误。
以下代码将一个int内存块分配给p
,然后尝试写入某个未知地址。
#include <stdlib.h>
int main(void)
{
int* p = malloc(sizeof(int));
p[1000] = 12;
return 0;
}
为什么这段代码没有引起分段错误,而它试图访问这个有点随机的地址?
相关
How undefined is undefined behavior? - 解释未定义的行为,但不解释为什么p[1000] = 12
指令不会引发段错误。
答案 0 :(得分:1)
通过执行p[1000] = 12;
,您只需在地址(p+1000)
上添加值即可。没有任何东西可以导致段错误。该地址可能是有效的,但p
未合法获取。
答案 1 :(得分:1)
当您启动程序时,OS会将程序内存分为可读(代码部分)和可写(数据部分以及堆)。现在它将取决于您正在引用的指针中存储的地址。
如果它指向有效的可写内存,则不会引发分段错误异常,否则将引发分段错误异常。
答案 2 :(得分:1)
以下代码为p分配一个int内存块,然后尝试在某个未知地址写入。
这不是一个“未知”的地址; p+4000
的系统上的地址为sizeof(int) == 4
。
大多数当前的操作系统都使用请求分页。在这样的系统上,第一次调用malloc
可能会分配一个新的页内存。常用页面大小为4096
,在此(可写)页面内的任何位置写入不会产生分段错误。
另一方面,该程序很可能会产生分段错误:
int main(void)
{
int* p = malloc(sizeof(int));
int j;
for (j = 1000; j < 100000; j++) p[j] = 12;
return 0;
}
答案 3 :(得分:0)
这完全取决于您运行此平台和操作系统的平台。如果您编译此代码并在没有MMU或MPU的处理器上运行它,那么您将不会收到任何异常/分段错误。
答案 4 :(得分:0)
据我了解,只要有程序就会引发段错误 试图访问未经授权的内存。
Segfault在您尝试访问非分页内存块时引发,没有任何授权。
p [1000]指向非分页区域吗?它是未定义的,但是在你的情况下,每个动态内存分配需要在x86系统中通常为4096字节的内存页面中分配,当你调用malloc时,如果找不到合适的内存块,它会在分配的页面中搜索空闲空间(在先前分配的页面或释放的页面中,将放置新的页面请求并分配内存页面。现在malloc为你保留了一部分分配的页面(如果请求的大小+标题小于页面大小)并返回它的指针。
现在,当您尝试访问p [1000]时,您实际上正在访问非保留(非malloced)区域,但该区域已被分页(之前分配的剩余部分),因此不会引发段错误,但如果您尝试访问更大的索引,如p [10000],你可能会得到段错误。
还有更多示例here