对于内存越界访问的笔记

        对于内存访问越界的操作在编译时期编译器是不会报错的,而在运行时期有可能发生段错误,有可能不会发生段错误。所以不能根据没有发生段错误来得出内存操作是正确的结论。下面介绍下这样定义的原因。

        虚拟内存系统能够操作的最小内存单元是页,每一页有固定的大小,比如4KB。每个页都有可读、可写、可执行的权限。当对一个可读可写的页上的内存进行了越界访问,而没有访问其他的页,则不会产生段错误,而是会改写越界部分的内容。例如:

#include <iostream>

using namespace std;


int main()
{
    int arr[3];
    int a = 0;
    arr[3] = 6;
    arr[4] = 9;
    
    cout<<arr[3]<<endl;
    cout<<arr[4]<<endl;
    cout<<"a = "<<a<<endl;

    return 0;
}

在Linux下gcc编译后输出结果是将a的值改写了,没有提示段错误。

在vs2010中会提示段错误,所以不能依赖编译器来检查是否内存操作正确。

 

在Linux环境下发生段错误的情况:内存越界访问了另一个不存在的页,或者这个页没有读写权限,会提示段错误。

#include <stdio.h>

int main()
{
    int arr[3];
    int i;
    for(i=0; i < 10000; i++)
    {
        arr[i] = i;
    }

    return 0;
}


当前页已经写完,超出了操作系统为该程序的数据区域指定的页组范围,当试图再执行写操作时会发生段错误。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值