请教一个内存越界写的问题,以下程序,系统到底做了些什么? 高分求教

时间:2023-01-11 23:58:08
请教一个内存越界写的问题,以下程序,系统到底做了些什么?高分求教

#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干的。

#2


哈哈,库只是作了内存分配及释放的系统调用而已,最终,对于内存的管理,还是系统来处理的。
对于段错误,是由系统给出的信号。

内部都做了啥?

#3


楼主的new后不做检查,系统会给你想不到的结果的..楼主的代码是c++那么应该还跟g++编译器有关系

如果使用非法内存空间,linux系统中用户空间里系统会直接kill该进程,如果在内核空间里系统会把自己挂起来产生oops

#4


呵呵,对于此问题,我可能还没有说清楚:

再重说一下:
我想问的是,对于内存管理,操作系统在发生内存越界写的时候,会作什么处理?当然除了进行内存合法性检验之外,如:判断是否在写程序无法访问的空间等。
此问题并不是测试是否会发生段错误,其实只想知道在未发生段错误的情形下,操作系统做了哪些事情?

因为毕竟我只申请了5个字节的空间,接着写了8个字节,如果此时未发生段错误,再释放5个字节,剩下的3个字节,系统如何处理?
在系统中有一个簿记的东西来标记我们所申请的内存大小,在释放时,系统会回收我们所申请的内存。

但奇怪的是:为何当不发生内存越界写的时候,程序每次申请的地址都是刚释放的那块(就本程序而言),如果发生了越界写,所申请的内存地址就不同了?
我所想知道的就是为何会有这种不同,此时操作系统做了什么处理?

#5


另:对于hefuhua 所提出的与g++编译器相关的问题的说法,我想说明一下:
此程序虽说使用了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干的。

#2


哈哈,库只是作了内存分配及释放的系统调用而已,最终,对于内存的管理,还是系统来处理的。
对于段错误,是由系统给出的信号。

内部都做了啥?

#3


楼主的new后不做检查,系统会给你想不到的结果的..楼主的代码是c++那么应该还跟g++编译器有关系

如果使用非法内存空间,linux系统中用户空间里系统会直接kill该进程,如果在内核空间里系统会把自己挂起来产生oops

#4


呵呵,对于此问题,我可能还没有说清楚:

再重说一下:
我想问的是,对于内存管理,操作系统在发生内存越界写的时候,会作什么处理?当然除了进行内存合法性检验之外,如:判断是否在写程序无法访问的空间等。
此问题并不是测试是否会发生段错误,其实只想知道在未发生段错误的情形下,操作系统做了哪些事情?

因为毕竟我只申请了5个字节的空间,接着写了8个字节,如果此时未发生段错误,再释放5个字节,剩下的3个字节,系统如何处理?
在系统中有一个簿记的东西来标记我们所申请的内存大小,在释放时,系统会回收我们所申请的内存。

但奇怪的是:为何当不发生内存越界写的时候,程序每次申请的地址都是刚释放的那块(就本程序而言),如果发生了越界写,所申请的内存地址就不同了?
我所想知道的就是为何会有这种不同,此时操作系统做了什么处理?

#5


另:对于hefuhua 所提出的与g++编译器相关的问题的说法,我想说明一下:
此程序虽说使用了C++的new来进行内存的处理,但可修改为malloc来测试。
对于C++中的new,最终会调用new运算子,而最终也会调用malloc或chunk_malloc

结果与平台肯定相关,上述测试程序在IBM下是不会有问题的,而且每次申请的地址不变,但在SUN及SUSE下必CORE。
其它平台未测试过

#6


太深了...
顶..

#7


这说明,debian和ibm下free掉8个字节,SUN及SUSE下free掉5个字节,种种不同,还是和编译器和c库的实现有关。