1

可能重复:
无效的读/写有时会产生分段错误,有时不会

我正在用 malloc 做一些实验,并在 linux m/c 上编写了这个非常小的程序:

int main(){
    int *p=NULL;
    p = (int *)malloc(10);
    *(p + 33*1000) = 5;
    free(p);
    return 0;
   }

该程序没有给出分段错误,但如果我将第 5 行更改为此 *(p + 34*1000) = 5; 然后它给出了分段错误。在我的系统上,页面大小为 4K。

我无法解释为什么它在 p 之后在大约 128Kb(34*1000 大约是 128K)处给出分段错误。

如果有人可以从 linux 内存管理的角度来解释这一点,那就太好了。

4

5 回答 5

4

您正在访问超出您为p两者分配的内存*(p+33*1000)*(p+34*1000)这是未定义的行为。您无法推理,因为它可能“工作”或崩溃或任何事情都可能发生。

于 2012-09-04T09:03:27.433 回答
2

您正在修改您自己尚未分配的内存 - 您正在写入的地址超出了数组的限制。每当您写入超出数组范围时,您都会面临段错误的风险 - 这取决于内存位置。取决于地址,它可能不会出现段错误,但这绝不是一件好事,结果将是不可预测的。

于 2012-09-04T09:04:28.577 回答
2

这个程序表现出未定义的行为(根据 C 标准),严格来说,没有什么可以解释的。

语言标准没有以任何方式描述内存管理是或应该如何在任何特定平台上的低级别实现。尽管您没有明确分配某些内存区域,但它们仍然可以访问。

于 2012-09-04T09:05:11.107 回答
0

可能是系统中的可用内存。在这种情况下,所有 <= 33 * 1000 将通过,所有 >= 34 *1000 将失败。

于 2012-09-04T12:41:23.883 回答
0

为 10 个整数分配空间后,您只能通过*(p+0), *(p+1), ... , *p(p+8),取消引用这 10 个整数*p(p+9)。没有更多的你超出了你分配的范围。

在其他地方取消引用可能意味着您正在尝试使用无效指针,因此会出现分段错误。

于 2012-09-04T09:07:42.340 回答