为什么这不会给出分段违规错误?

时间:2014-04-10 17:06:40

标签: c arrays malloc

#include <stdio.h>
#include <stdlib.h>

int noOfIntegers = 2;

struct stack {
  int *s;
  int top;
} st;

void push(int item) {
  st.top++;
  st.s[top] = item;
}

int main() {
  st.s = malloc (2 * (sizeof(int)));
  st.top = -1;
  push(1);
  push(2);
  push(3);
  return 0;
}

我不明白为什么这不会给出分段错误,因为我有2 int的malloc空间,并且在指针所指向的数组中插入3。

3 个答案:

答案 0 :(得分:14)

更新:这个问题是my ATBG column in May 2014的灵感来源。谢谢你提出的好问题!


想象一个巨大的雷区,延伸到地平线。如果你开过矿井,BOOM,你的汽车就会爆炸。

在雷区的中间是未开采的停车场,每个都有四千个编号的空间。每个停车场都有一个号码。每个空间都有一个数字。有些地段彼此相邻,有些则没有。

你打电话给停车场经理并请求八个空格。你被告知你的空间是100,空间1234到1241.

你驾驶汽车前往该地段,在1243号空间找到一辆汽车,将汽车停放在该地点,然后驾驶其他人开车。

为什么你的车没爆?因为你不在雷区。你破坏了规则吗?当然。你偷了别人的停车位。不要这样做。他们&#39;可能会是疯了找不到自己的车停放在那里。但他们并没有打击你。

然后你驾驶那辆车去4003,但是这个地方只有4000个点,所以你开车去4000点,然后开车离开停车场的右边到地点右边的三个地方4000.事实证明,这是停车场101的第3号现场。你将偷来的车停在那里并偷走以前在该地点的汽车。

为什么你的车没爆?因为你不在雷区。

然后你开车到100号的8003点,只有4000个点,一直到100号,一直到101号,在它的右端,哦,哦,这次你进入雷区。

为什么你的车会爆炸?因为你在雷区。

现在很明显为什么写入你不拥有的记忆并不能保证分段错误?分段错误意味着&#34;你在一个内存页面中甚至不是一个有效的页面&#34;。如果您使用了您不应该使用的有效页面的一部分,操作系统就不会知道这一点。

答案 1 :(得分:3)

malloc从堆内存中分配空间;您已在堆上分配了2 ints,并写了3 ints

程序的内存通常以中等大小的块分配,以便对内存管理器更有效。

请求1个字节?你可能有8个字节 请求7个字节?你可能有8个字节 请求14个字节?你可能有16个字节 (或者至少16字节......)

您只能保证访问您实际请求的内存,但有时您可以在几个字节之外写入而不会导致问题。没有承诺过多的写入是安全的。你可能得到一个段错误,你可能不会!

答案 2 :(得分:1)

如果你幸运的话,它会给你一个段错误或什么都没有。

你在一个可以包含其他变量使用数据的地方写东西。

修改 这不会产生和错误,因为你写入了为你的程序保留的内存空间,你的操作系统什么也没说,但如果你继续可能会擦除10 000次,那么你将删除其他程序的数据,操作系统会关闭你的程序以保护其他程序