c++学习笔记(一):内存分区模型

内存分区模型

c++在执行时,将内存大方向划分为4个区域

  • 代码区:存放函数体的二进制代码,由操作系统进行管理(编写的所有代码都会存放到该处)
  • 全局区:存放全局变量和静态变量以及常量
  • 栈区:由编译器自动分配释放,存放函数的参数值,局部变量等
  • 堆区:由程序员分配和释放,若程序员不释放,程序结束时由操作系统回收

内存四区的意义:

不同区域存放的数据,将被赋予不同的生命周期,能让我们更加灵活地进行编程


程序运行前

在程序编译后,生成了exe可执行程序,未执行该程序前分为两个区域

代码区:

​ 存放CPU执行的机器指令

​ 代码区是共享的,共享的目的是对于频繁被执行的程序,只需要内存中有一份代码即可

​ 代码区是只读的,使其只读的原因是防止程序意外地修改了他的指令

全局区:

​ 全局变量和静态变量存放于此

​ 全局区还包含了常量区,字符串常量和其他常量也存放在此

该区域的数据在程序结束后由操作系统释放


程序运行后

栈区:

​ 由编译器自动分配释放,存放函数的参数值,局部变量等

​ Tips:不要返回局部变量的地址,栈区开辟的数据由编译器自动释放

int* func(int b)//形参数据也会放到栈区
{
    int b = 100;
    int a=10;//局部变量 存放在栈区,栈区的数据在函数执行完后自动释放
    return &a;//返回局部变量的地址
}

int main() 
{
	//接受func函数的返回值
	int * p = func(1);
    
	std::cout <<* p <<std::end1; //第一次可以打印正确结果,是因为编译器做了保留
	std::cout <<* p <<std::end1; //第二次打印乱码,是因为第二次不再做保留
	
    system("pause");
	
    return 0;
}

堆区:

​ 由程序员分配和释放,若程序员不释放,程序结束时由操作系统回收

​ 在c++中主要利用new在堆区开辟内存

int * func()
{
    //利用new关键字  可以将数据开辟到堆区
    //指针  本质上也是局部变量,放在栈上,但指针保存的数据是存放在堆区
    int * p = new int(10); //这里new返回了一个地址给指针p
    return p;
}

int main()
{
    //在堆区开辟数据
    int * p = func();
    
    //不主动释放内存的话堆区数据一直存在,因此四次打印结果无误
    std::cout<<*p<<std::endl;
    std::cout<<*p<<std::endl;
    std::cout<<*p<<std::endl;
    std::cout<<*p<<std::endl;
    
    return 0;
}

new操作符

c++中利用new操作符在堆区开辟数据

堆区开辟的数据,由程序员手动开辟、手动释放,释放利用操作符delete

语法:new 数据类型

//1.new的基本语法
int * func()
{
    //在堆区创建整型数据
    //new返回的是该数据类型的指针
    int * p = new int(10); 
    return p;
}

void test1()
{
    int * p = func();
    std::cout<<*p<<std::endl;
    std::cout<<*p<<std::endl;
    std::cout<<*p<<std::endl;
    //堆区的数据由程序员管理开辟,管理员管理释放
    //如果想释放堆区的数据,利用关键字delete
    delete p;
    std::cout<<*p<<std::endl;//内存已经被释放,再次访问是非法操作会报错
    return 0;
}

//2.在堆区利用new开辟数组
void test2()
{
    //在堆区创建10个元素整型数据的数组
    int * arr = new int[10]; //10代表数组有10个元素
    
    //赋值
    for (int i = 0;i < 10; i++)
    {
        arr[i] = i + 100;
    }
    //输出
    for (int i = 0;i < 10; i++)
    {
        std::cout<<arr[i]<<std::endl;
    }
    //释放堆区数组
    //释放堆区数组时,要加[]才能成功释放
    delete[] arr;
}
posted @ 2024-06-14 16:06  StaDark  阅读(63)  评论(2)    收藏  举报