超越数组和分段错误

时间:2012-11-30 12:25:25

标签: c posix

超出数组大小的数组索引是否会在可靠的真实POSIX系统(如GNU / Linux)上导致分段错误?

我认为不,如果访问的位置仍然位于同一页面,但想确定。

1 个答案:

答案 0 :(得分:5)

不,不一定。分段违规SIGSEGV由内核处理,仅在无效的内存访问时调用。

数组是编译时结构,POSIX也是如此。另一方面,分段违例是一个运行时错误,表明您试图对一块您不允许(读/写/执行)或未映射的虚拟内存执行某些操作(内存控制器不知道)什么物理资源应该支持它)。此时,内核将向您的进程发送信号SiGSEGV,默认行为是退出,但可以覆盖。

您甚至经常会看到像这样的C代码,它指示编译器以结构变量大小的形式访问结构后面的内存:

struct s {
    // some other elements
    int id; // whatever other elements

    char appended_array[0];
};

// ....

struct s* mystruct = malloc(sizeof(struct s) + length_of_array_i_need);

// work with mystruct->appended_array[i]
// at this point mystruct->appended_array[3] is valid C and the compiler will not even issue a warning,
// though if it lies outside of your allowed VM then the kernel will issue a SIGSEGV

仅因为数组未定义超出某个索引,并不一定意味着它后面没有有效的内存。