【问题标题】:C | Static array: why does writing out-of-bounds not result in exception? [duplicate]C |静态数组:为什么越界写入不会导致异常? [复制]
【发布时间】:2019-06-16 07:32:53
【问题描述】:

在 C 语言中,我注意到我可以写入 static 数组,例如:

static char a[10] = {0};

for (int i=0; i<20; i++) {
    a[i] = 'a'; // Should fail when i > 9
}

我预计会出现分段错误,但它执行得很好。

如果静态数组是在栈上分配的,那是有道理的,但不是,那为什么会这样呢?

注意:静态 int 数组的行为类似。没有检查其他类型。

谢谢。

编辑:这不是重复的,因为其他问题与 static 数组无关。与“常规”数组不同,静态数组在 BSS 中分配。行为可能会有所不同,这就是我单独询问的原因。

【问题讨论】:

  • 您能解释一下为什么您认为它会导致异常吗?如果我们不知道您误解了什么,就很难纠正您的误解。我想不出任何理由你会期待一个例外。您是否想象单个字节可以被写保护或其他什么?
  • 欢迎来到未定义行为的世界。
  • @DavidSchwartz,我正在写信给我没有要求分配的地址。它不应该导致某种异常吗?
  • @RazMoshe 您是否认为当您分配两个或三个字节时,系统会以某种方式使这两个或三个字节可访问,而接下来的几个字节以某种方式受到写保护?这不是内存管理的工作原理。
  • @RazMoshe 内存保护在您的系统上可能最小 4KB 的页面中完成。如果您不跨越页面边界,您将不会遇到异常,因为地址都将具有相同的内存保护。如果每次任何线程尝试分配或释放一个字节时,都必须为进程内存更改操作系统级别的内存保护,那么性能将非常糟糕。期望违反内存保护是不合理的。

标签: c arrays linux static


【解决方案1】:

只有在实际尝试写入内存时才会出现分段错误 那是一个非法地址。您的示例代码写入超出了您为数组分配的内容,但这不是操作系统确定您可以使用的地址之外的地址。 即使您没有遇到分段错误,您的示例代码也可能会破坏代码中的其他数据结构并导致程序出现重大错误行为,甚至更糟糕的是,它可能会导致间歇性且难以调试的错误行为。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多