zoukankan      html  css  js  c++  java
  • C++内存分配中一个有趣的小问题(原来博客园已经发布的文章不能重新用markdown来写呀)

    以下代码测试环境:vs2019

    问题的提出

    执行这么一段代码,看看会发生什么:

    int main()
    {
            int arr[5] = { 0 };
    	arr[5] = 1;
    }
    

    毫无疑问,会报错,因为访问越界了。


    再看看另一段代码:

    int arr[5] = { 0 };
    int main()
    {
        arr[5] = 1;
    }
    

    与上面的代码相比几乎没什么差别,仅仅把arr的定义和初始化搬到了函数外面,但执行程序却没有出错。

    类似的还有这么一段代码:

    int main()
    {
        static int arr[5] = { 0 };
        arr[5] = 1;
    }
    

    同样也能执行成功,那么这是为什么呢?


    问题的探索

    以下这段话摘自

    C++中内存分为5个区,分别是自由存储区全局/静态存储区常量存储区
    是操作系统中的术语,是操作系统所维护的一块特殊内存,用于程序的内存动态分配,C语言使用malloc从堆上分配内存,使用free释放已分配的对应内存。
    :在执行函数时,函数内局部变量的存储单元都可以在上创建,函数执行结束时这些存储单元自动被释放。内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
    自由存储区自由存储区C++基于new操作符的一个抽象概念,凡是通过new操作符进行内存申请,该内存即为自由存储区
    全局/静态存储区:这块内存是在程序编译的时候就已经分配好的,在程序整个运行期间都存在。例如全局变量静态变量
    常量存储区:这是一块比较特殊的存储区,他们里面存放的是常量(const),不允许修改。

    上面的问题涉及到两个区:全局/静态存储区


    个人的推测

    基于以上结果,我有个不成熟的小推测:

    • 的空间是系统预定分配好的,假如我定义了int arr[5],那么系统就一定给我5*4(32位系统下)个字节的空间,系统不允许我访问超过这个空间的地址上的数据。
    • 全局/静态存储区则不同,当我定义int arr[5]时,系统给我返回arr首地址,我不仅可以根据这个首地址去访问20个字节的内容,还可以访问这二十个字节以外的内容。
  • 相关阅读:
    MyBatis笔记:xml映射文件
    MyBatis笔记:xml配置文件
    JSP获取当前系统时间并显示
    使用<jsp:forward>和<jsp:param>
    JSP简单总结
    网页版学生管理系统简易版DOM
    当为servlet配置时出现servlet标签报错
    给js的事件驱动函数添加快捷键
    js的表格对象和DOM联合操作
    Centos7安装Greenplum5.3单机版教程
  • 原文地址:https://www.cnblogs.com/XiaoXiaoShuai-/p/12452795.html
Copyright © 2011-2022 走看看