char *s = sbrk(some_num);
if (s != (char *)-1) {
some_struct = (SomeStruct *)s;
some_struct->num = 8; //num is an int [*SEG FAULT OCCURS ON THIS LINE*]
}
使用gdb调试:
p some_struct => (SomeStruct *) 0xef7100
p some_struct->num => 0
从之前的q / a中,我了解当某些内容为NULL时会发生seg错误,但在此示例中,some_struct,some_struct-&gt; num和8都是非NULL 。< / p>
为什么会发生分段错误?如何将some_struct-&gt; num设置为某个int值?
答案 0 :(得分:1)
指针some_struct需要指向一些有效的内存。如果函数some_function返回指向某个局部volatile变量的指针,那么当some_function退出时该变量将丢失。
为了避免segfault,你可以将some_function中的局部变量声明为static,或者你可以通过让some_function调用malloc来从堆中分配内存。如果some_function使用malloc分配内存,则调用者有责任确保稍后释放内存。
避免segfault的另一种方法是不将指针返回到局部变量而是返回全局变量。但是,大多数人都同意应该避免全局变量。
答案 1 :(得分:0)
熟悉虚拟内存的概念是值得的,它是当今大多数现代操作系统的基础。
在具有虚拟内存的操作系统下,每个内存地址(实际上是虚拟地址)与电话号码类似,因为您无法在每个10位数的组合中呼叫某人。
您只需拨打电话簿中列出的号码即可拨打电话。
否则你会听到“抱歉,这个号码目前无法使用”。
同样,只有每个进程的“页表”中列出的那些虚拟地址(始终由操作系统自动和透明地维护)才能对访问进程有效。
SEGV是操作系统的说法“抱歉,这个虚拟地址目前无法使用。”
malloc
(和sbrk
)基本上可以要求操作系统为您分配指定大小的内存块,并将其地址注册到页表。