#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。
答案 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次,那么你将删除其他程序的数据,操作系统会关闭你的程序以保护其他程序