当所有值都是非空的时,结构的分段错误

时间:2014-10-12 18:09:06

标签: c

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值?

2 个答案:

答案 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)基本上可以要求操作系统为您分配指定大小的内存块,并将其地址注册到页表。