• C++:内存分区



    前言:最近正在学习有关static的知识,发觉对C++的内存分区不是很了解,上网查了很多资料,遂将这几天的学习笔记进行了简单整理,发表在这里

    • 栈区(stack):主要用来存放函数的参数以及局部变量。栈区由系统进行内存管理,在函数完成执行时,系统会自行释放栈区的内存,而不需要用户参与管理。整个程序的栈区的大小可以在编译器中由用户自行设定,默认的栈区大小为3M


     • 堆区(heap):由用户手动申请,手动释放。如果用户忘记对其所申请的内存资源进行释放,该内存资源可能会在程序结束时由操作系统(OS)进行释放(也可能不会)

    [注意]:

    1.C++系统内存分区中的堆和数据结构中的堆是不同的,但C++内存分区中的堆对系统资源的分配方式和数据结构中的链表却十分相似

    2.在C中用户通常用malloc进行内存的申请,用free进行内存的释放;而在C++中用户通常用new进行内存的申请,用delete进行内存的释放(C++同样支持malloc/free方式)。

    3.通常认为C++中有两个动态内存区域。通过new/delete方式进行内存资源的分配和释放的称为自由存储区(free store),而通过malloc/free方式进行内存资源的分配和释放的称为堆区(heap)。但本质上来说很多编译器中的new操作符是通过malloc进行内存申请的,因此可以将堆区理解为自由存储区的一个具体实现,虽然二者不完全相同,但很多时候可以混为一谈。 (如果想细究堆区和自由存储区的不同,可以参考这个博客:http://www.cnblogs.com/QG-whz/p/5060894.html

    4.new与malloc的几点不同:

      • malloc是C语言中的函数,而new是C++中的操作符

      • malloc申请之后返回的类型是void*,而new返回的指针则是带有特定数据类型的

      • malloc只负责内存的分配而不会调用类的构造函数,而new不仅会分配内存,而且会自动调用类的构造函数


     • 静态区(全局区)(static):用来存放程序的全局变量静态变量在C语言中,初始化的全局变量和静态变量放在一块内存区域中,而未初始化的全局变量和静态变量放在与之相邻的另一块内存区域中。而在C++中则没有在静态区中将初始化的和未初始化的变量进行分开存储,因为C++会对未初始化的全局变量和静态变量进行默认初始化(一般默认初始化为0)。该区域存储的数据会在程序结束后由系统来释放。

     [注意]:

    全局变量和静态全局变量在C++中的存储方式是一样的,但不同的是全局变量在整个源代码中都是可以使用的,而静态全局变量只能在当前文件中使用。比如一个程序有3个文件a.cpp、b.cpp和c.cpp,如果在文件a.cpp中定义了一个全局变量x,那么该变量x在文件a.cpp、b.cpp和c.cpp中都可以使用;但如果在文件a.cpp中定义了一个静态全局变量y,那么该变量y只能在文件a.cpp中使用文件b.cpp和文件c.cpp都不可以使用该静态全局变量y


      • 常量存储区:用来存储程序中的常量,比如const常量,字符串常量等都存储在这个区域。该区域存储的数据会在程序结束后由系统来释放

    [注意]:

    1.在程序运行期间,该区域中存储的常量是全局可见的。

    2.当我们定义char *ptr="Tomwenxing"时,字符串“Tomwenixng”就存储在这个区域


     • 代码区:存放程序体的二进制代码。比如我们在程序中自定义的函数,其函数体就是以二进制代码的形式存储在这个区域的


    • 实例:

     1 #include<iostream>
     2 #include<cstring>
     3 using namespace std;
     4 int value1=10; //全局变量:存储在静态区(全局区) 
     5 const int value2=10; //const常量:存储在常量区
     6 static int value3=10; //static变量:存储在静态区 (全局区)
     7 
     8 //函数func:存储在代码区 
     9 void func(int a){  //a为函数参数:存储在栈区 
    10     int temp=10; //局部变量:存储在栈区
    11     static int temp2; //静态变量(默认初始化为0):存储在静态区(全局区) 
    12     cout<<"This is func"<<endl; // "This is func"是字面值常量:存储在常量区 
    13 }
    14 
    15 //函数main:存储在代码区 
    16 int main(){
    17     int value4=10; //局部变量;存储在栈区
    18     char *ptr1=NULL; //局部变量:存储在栈区
    19     static int value5=10; //静态变量:存储在静态区(全局区)
    20     char *ptr2="Tomwenxing"; //ptr2为局部变量:存储在栈区; "Tomwenxing"为字面值常量:存储在常量区
    21     ptr1=(char*)malloc(sizeof(char)*100); // malloc动态开辟的空间:存储在堆区
    22     strcpy(ptr1,"Hello"); //"Hello"是字面值常量:存储在常量区 
    23     free(ptr1);
    24     int *ptr3=new int; //ptr3为局部变量:存储在栈区;new动态开辟的空间:存储在堆区(自由存储区) 
    25     delete ptr3;
    26     return 0; 
    27 } 
  • 相关阅读:
    java中传值与传引用
    microsofr visual studio编写c语言
    openfile学习笔记
    在 Windows 和 Linux(Gnome) 环境下 从命令界面打开网页的方式
    使用vsphere client 克隆虚拟机
    route命令
    linux rpm问题:怎样查看rpm安装包的安装路径
    【leetcode】415. 字符串相加
    【leetcode】面试题 17.01. 不用加号的加法
    【leetcode】989. 数组形式的整数加法
  • 原文地址:https://www.cnblogs.com/duwenxing/p/7461269.html
Copyright © 2020-2023  润新知