84讲 程序的内存模型(此时步入面向对象阶段)
内容纲要

内存分区模型:laughing:

C++ 程序再执行时,将内存大方向划分为4 个区域

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

内存四区的意义:
不同的区域存放的数据,赋予不同的生命周期,使编程更灵活


程序运行前

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

代码区

  1. 存放 CPU 执行的机器指令
  2. 代码区是 共享 的,共享的目的是对于频繁被执行的程序,只需要在内存中有一份代码即可。(比如说你同时打开同一个程序两次,登录2个QQ)
  3. 代码区是 只读 的,使其只读的原因是防止程序意外的修改了它的指令。

全局区

  1. 全局变量静态变量 存放于此。
  2. 全局区还包含了 常量区字符串常量其它常量 也存放于此。
  3. 该区域的数据在程序结束后由操作系统释放。:confused:

file

  • 示例代码
#include <iostream>
#include "string"

using namespace std;

int global_a = 10; //全局变量
int global_b = 10;

const int c_global_a = 10;
const int c_global_b = 10;

//int s_global_a = 20;

void main1() {

    //全局区

    //全局变量、静态变量、常量

    //创建普通局部变量
    int a = 10; //局部变量
    int b = 10;

    cout << "局部变量a 的地址为:" << (int)&a << endl;
    cout << "局部变量b 的地址为:" << (int)&b << endl;
    cout << "全局变量a 的地址为:" << (int)&global_a << endl;
    cout << "全局变量b 的地址为:" << (int)&global_b << endl;

    //静态变量 在普通变量前面加static ,属于静态变量
    static int s_global_a = 10;
    static int s_global_b = 10;
    //静态变量和局部变量不能冲突。但是在全局变量中定义和静态变量同名时,编译器不报错,可以运行。。
    //虽然不报错,但是如果调用同名的变量,它会调用为静态变量中的值。
    cout << "静态变量a 的地址为:" << (int)&s_global_a << endl;  
    //cout << "s_global_a的值为: " << s_global_a << endl;  //10
    cout << "静态变量b 的地址为:" << (int)&s_global_b << endl;         

    //常量
    //字符串常量
    cout << "字符串常量的地址为:" << (int)&"hello" << endl;   //常

    //const 修饰的变量
    //const 修饰的全局变量,const 修饰的局部变量、
    cout << "全局常量 c_global_a 的地址为:" << (int)&c_global_a << endl;
    cout << "全局常量 c_global_b 的地址为:" << (int)&c_global_b << endl;

    int c_local_a = 10;
    int c_local_b = 10;
    cout << "局部常量 c_local_a 的地址为:" << (int)&c_local_a << endl; 
    cout << "局部常量 c_local_b 的地址为:" << (int)&c_local_b << endl; 

}

void hello() {
    //cout << (int)&a;

}

结论:

  • C++中在程序运行前分为 全局区代码区
  • 代码区的特点是共享只读
  • 全局区中存放全局变量、静态变量、常量
  • 常量区中存放 const修饰的全局常量字符串常量

程序运行后

栈区:

  1. 由编译器自动分配释放,存放函数的参数值,局部变量等。
    2.注意事项:不要返回局部变量的地址!!!!栈区开辟的数据由编译器自动释放

#include <iostream>

using namespace std;

int* func(int b) //形参数据也会存在于栈区
{
    b = 100;
    int a = b; //局部变量,存放在栈中,生命周期随着函数的结束而销毁。
    return &b;  //返回局部变量的地址
}

void main() {
    int* p = func(10);
    //第一次可以打印正确的数字,因为编译器做了保留,怕程序员误操作
    cout << "栈返回的地址打印解指针:   " << *p << endl;
    //第二次数据就不再保留了。
    cout << "栈返回的地址打印解指针:   " << *p << endl; 

    system("pause");
}

堆区:

  1. 由程序员分配释放,若程序员不释放,程序结束时由操作系统回收。
  2. 在C++ 中主要利用new 在堆开辟内存。

//利用new 关键字, 可以将数据开辟到堆区。
//指针 本质也是一个局部变量,存放于栈上,下方代码中 指针 保存的数据放在堆区!

file

#include<iostream>
using namespace std;

int * func()
{
    int * a = new int(10);
    return a;
}

void main()
{
    //在堆区开辟数据。
    int * p = func();

    cout << "局部变量中用new 开辟的内存地址解指针:  " << *p << endl;
    cout << "局部变量中用new 开辟的内存地址解指针:  " << *p << endl;
    cout << "局部变量中用new 开辟的内存地址解指针:  " << *p << endl;
    system("pause");
}

new操作符

  • C++ 中利用new 操作符在堆区开辟数据
  • 堆区开辟的数据,由程序员手动开辟,手动释放,释放操作符用 delete
  • 语法: new 数据类型
  • 利用new 创建的数据,会返回数据对应类型的指针
#include<iostream>

using namespace std;

//1、new的基本语法
double * func()
{
    //在堆区创建整型数据
    //new 返回是 该数据类型的指针。
    double * a = new double(10.1);
    return a;
}

int* test1()
{
    //用new 在堆中创建数组
    int* b = new int[10];
    for (size_t i = 0; i < 10; i++)
    {
        b[i] = 100 + i;
    }
    for (size_t j = 0; j < 10; j++)
    {
        cout << b[j] << endl;
    }
    return b;
}

void printInfo() {
    double* p = func();
    cout << *p << endl;
    cout << *p << endl;
    cout << *p << endl;
    delete p;
    cout << *p << endl; //内存已经被释放,再次访问会非法操作报错。
}

void main()
{
    //printInfo();
    int *p = test1();
    delete[] p;
}
  • 注意删除数组的时候要用 delete[] p
  • 要养成创建删除的好习惯,不然内存泄漏。。。
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇