#include <string.h>
int
main (int argc, char* argv[])
{
char* pTest = 0;
for (int i = 0; i < 10000; i++)
{
pTest = new char[5];//奇怪的是,如果下一条语句没有发生越界写,向堆申请的内存地址保持不变,但发生越界写后,地址不定
memset (pTest, 0, 8);//操作系统除了作非法性判断外,是否修改了pTest所指向的实际内存大小,如此时修改为8
delete[] pTest;//操作系统此时释放的是多少内存,8个字节还是5个字节?
pTest = 0;
}
return 0;
}
请大家有兴趣,可以在不同的操作系统上跑跑这个程序,会有不同的表现
我想问的是,对于内存管理,操作系统在发生内存越界写的时候,会作什么处理?当然除了进行内存合法性检验之外,如:判断是否在写程序无法访问的空间等。
很奇怪的是,如果没有发生越界写,pTest的地址每次的值都会一样,但一旦发生了越界写,pTest所指向的地址会发生改变,这时操作系统到底在做什么?
7 个解决方案
#1
我想问的是,对于内存管理,操作系统在发生内存越界写的时候,会作什么处理?
在linux下会提示“段错误(Segment Fault)”,这是libc干的。
在linux下会提示“段错误(Segment Fault)”,这是libc干的。
#2
哈哈,库只是作了内存分配及释放的系统调用而已,最终,对于内存的管理,还是系统来处理的。
对于段错误,是由系统给出的信号。
内部都做了啥?
对于段错误,是由系统给出的信号。
内部都做了啥?
#3
楼主的new后不做检查,系统会给你想不到的结果的..楼主的代码是c++那么应该还跟g++编译器有关系
如果使用非法内存空间,linux系统中用户空间里系统会直接kill该进程,如果在内核空间里系统会把自己挂起来产生oops
如果使用非法内存空间,linux系统中用户空间里系统会直接kill该进程,如果在内核空间里系统会把自己挂起来产生oops
#4
呵呵,对于此问题,我可能还没有说清楚:
再重说一下:
我想问的是,对于内存管理,操作系统在发生内存越界写的时候,会作什么处理?当然除了进行内存合法性检验之外,如:判断是否在写程序无法访问的空间等。
此问题并不是测试是否会发生段错误,其实只想知道在未发生段错误的情形下,操作系统做了哪些事情?
因为毕竟我只申请了5个字节的空间,接着写了8个字节,如果此时未发生段错误,再释放5个字节,剩下的3个字节,系统如何处理?
在系统中有一个簿记的东西来标记我们所申请的内存大小,在释放时,系统会回收我们所申请的内存。
但奇怪的是:为何当不发生内存越界写的时候,程序每次申请的地址都是刚释放的那块(就本程序而言),如果发生了越界写,所申请的内存地址就不同了?
我所想知道的就是为何会有这种不同,此时操作系统做了什么处理?
再重说一下:
我想问的是,对于内存管理,操作系统在发生内存越界写的时候,会作什么处理?当然除了进行内存合法性检验之外,如:判断是否在写程序无法访问的空间等。
此问题并不是测试是否会发生段错误,其实只想知道在未发生段错误的情形下,操作系统做了哪些事情?
因为毕竟我只申请了5个字节的空间,接着写了8个字节,如果此时未发生段错误,再释放5个字节,剩下的3个字节,系统如何处理?
在系统中有一个簿记的东西来标记我们所申请的内存大小,在释放时,系统会回收我们所申请的内存。
但奇怪的是:为何当不发生内存越界写的时候,程序每次申请的地址都是刚释放的那块(就本程序而言),如果发生了越界写,所申请的内存地址就不同了?
我所想知道的就是为何会有这种不同,此时操作系统做了什么处理?
#5
另:对于hefuhua 所提出的与g++编译器相关的问题的说法,我想说明一下:
此程序虽说使用了C++的new来进行内存的处理,但可修改为malloc来测试。
对于C++中的new,最终会调用new运算子,而最终也会调用malloc或chunk_malloc
结果与平台肯定相关,上述测试程序在IBM下是不会有问题的,而且每次申请的地址不变,但在SUN及SUSE下必CORE。
其它平台未测试过
此程序虽说使用了C++的new来进行内存的处理,但可修改为malloc来测试。
对于C++中的new,最终会调用new运算子,而最终也会调用malloc或chunk_malloc
结果与平台肯定相关,上述测试程序在IBM下是不会有问题的,而且每次申请的地址不变,但在SUN及SUSE下必CORE。
其它平台未测试过
#6
太深了...
顶..
顶..
#7
这说明,debian和ibm下free掉8个字节,SUN及SUSE下free掉5个字节,种种不同,还是和编译器和c库的实现有关。
#1
我想问的是,对于内存管理,操作系统在发生内存越界写的时候,会作什么处理?
在linux下会提示“段错误(Segment Fault)”,这是libc干的。
在linux下会提示“段错误(Segment Fault)”,这是libc干的。
#2
哈哈,库只是作了内存分配及释放的系统调用而已,最终,对于内存的管理,还是系统来处理的。
对于段错误,是由系统给出的信号。
内部都做了啥?
对于段错误,是由系统给出的信号。
内部都做了啥?
#3
楼主的new后不做检查,系统会给你想不到的结果的..楼主的代码是c++那么应该还跟g++编译器有关系
如果使用非法内存空间,linux系统中用户空间里系统会直接kill该进程,如果在内核空间里系统会把自己挂起来产生oops
如果使用非法内存空间,linux系统中用户空间里系统会直接kill该进程,如果在内核空间里系统会把自己挂起来产生oops
#4
呵呵,对于此问题,我可能还没有说清楚:
再重说一下:
我想问的是,对于内存管理,操作系统在发生内存越界写的时候,会作什么处理?当然除了进行内存合法性检验之外,如:判断是否在写程序无法访问的空间等。
此问题并不是测试是否会发生段错误,其实只想知道在未发生段错误的情形下,操作系统做了哪些事情?
因为毕竟我只申请了5个字节的空间,接着写了8个字节,如果此时未发生段错误,再释放5个字节,剩下的3个字节,系统如何处理?
在系统中有一个簿记的东西来标记我们所申请的内存大小,在释放时,系统会回收我们所申请的内存。
但奇怪的是:为何当不发生内存越界写的时候,程序每次申请的地址都是刚释放的那块(就本程序而言),如果发生了越界写,所申请的内存地址就不同了?
我所想知道的就是为何会有这种不同,此时操作系统做了什么处理?
再重说一下:
我想问的是,对于内存管理,操作系统在发生内存越界写的时候,会作什么处理?当然除了进行内存合法性检验之外,如:判断是否在写程序无法访问的空间等。
此问题并不是测试是否会发生段错误,其实只想知道在未发生段错误的情形下,操作系统做了哪些事情?
因为毕竟我只申请了5个字节的空间,接着写了8个字节,如果此时未发生段错误,再释放5个字节,剩下的3个字节,系统如何处理?
在系统中有一个簿记的东西来标记我们所申请的内存大小,在释放时,系统会回收我们所申请的内存。
但奇怪的是:为何当不发生内存越界写的时候,程序每次申请的地址都是刚释放的那块(就本程序而言),如果发生了越界写,所申请的内存地址就不同了?
我所想知道的就是为何会有这种不同,此时操作系统做了什么处理?
#5
另:对于hefuhua 所提出的与g++编译器相关的问题的说法,我想说明一下:
此程序虽说使用了C++的new来进行内存的处理,但可修改为malloc来测试。
对于C++中的new,最终会调用new运算子,而最终也会调用malloc或chunk_malloc
结果与平台肯定相关,上述测试程序在IBM下是不会有问题的,而且每次申请的地址不变,但在SUN及SUSE下必CORE。
其它平台未测试过
此程序虽说使用了C++的new来进行内存的处理,但可修改为malloc来测试。
对于C++中的new,最终会调用new运算子,而最终也会调用malloc或chunk_malloc
结果与平台肯定相关,上述测试程序在IBM下是不会有问题的,而且每次申请的地址不变,但在SUN及SUSE下必CORE。
其它平台未测试过
#6
太深了...
顶..
顶..
#7
这说明,debian和ibm下free掉8个字节,SUN及SUSE下free掉5个字节,种种不同,还是和编译器和c库的实现有关。