de风——【从零开始学C++】(五):内存管理

目录

前言

[(一)C/C++ 的内存分布](#(一)C/C++ 的内存分布)

[1. 基础概念解释](#1. 基础概念解释)

[2. 代码例子演示](#2. 代码例子演示)

[【示例 1:不同变量的内存位置验证】](#【示例 1:不同变量的内存位置验证】)

例题练习:

[(二)C 语言中的动态内存管理](#(二)C 语言中的动态内存管理)

[1. 基础概念解释](#1. 基础概念解释)

[2. 代码例子演示](#2. 代码例子演示)

[【示例 2:malloc 的基本用法】](#【示例 2:malloc 的基本用法】)

[【示例 3:calloc 的用法 - 自动初始化】](#【示例 3:calloc 的用法 - 自动初始化】)

[【示例 4:realloc 的用法 - 调整内存大小】](#【示例 4:realloc 的用法 - 调整内存大小】)

[(三)C++ 中的内存管理(new、delete)](#(三)C++ 中的内存管理(new、delete))

[1. 基础概念解释](#1. 基础概念解释)

[2. 代码例子演示](#2. 代码例子演示)

[【示例 5:new、delete 操作内置类型】](#【示例 5:new、delete 操作内置类型】)

[【示例 6:new、delete 操作自定义类型】](#【示例 6:new、delete 操作自定义类型】)

[(四)operator new 与 operator delete 函数](#(四)operator new 与 operator delete 函数)

[1. 基础概念解释](#1. 基础概念解释)

[2. 代码例子演示](#2. 代码例子演示)

[【示例 7:operator new/delete 的直接使用】](#【示例 7:operator new/delete 的直接使用】)

[(五)new 与 delete 的实现原理](#(五)new 与 delete 的实现原理)

[1. 基础概念解释](#1. 基础概念解释)

[内置类型(int、double 等):](#内置类型(int、double 等):)

自定义类型(类对象):

[2. 代码例子演示](#2. 代码例子演示)

[【示例 8:new/delete 原理验证】](#【示例 8:new/delete 原理验证】)

[(六)malloc/free 和 new/delete 的区别](#(六)malloc/free 和 new/delete 的区别)

[1. 基础概念解释](#1. 基础概念解释)

[2. 代码例子演示](#2. 代码例子演示)

[【示例 9:对比演示 - 错误处理方式】](#【示例 9:对比演示 - 错误处理方式】)

总结

下期预告



前言

大家好,我是你们的小小的风呀!今天是【从零开始学 C++】专题的第五篇,我们来聊聊一个非常重要但又容易让新手头疼的话题 ------内存管理

为什么要学内存管理?简单说:

  • 程序运行的本质就是在操作内存

  • 懂内存管理才能写出高效、稳定的程序

  • 这是面试必考题!面试官最爱问的就是 malloc 和 new 的区别

  • 很多 bug(内存泄漏、野指针)都源于对内存管理的不理解

别担心,今天我用大白话 + 代码示例,带你彻底搞懂内存管理!坐稳扶好,我们发车~


(一)C/C++ 的内存分布

1. 基础概念解释

首先,我们要明白:程序运行时,内存不是乱存的,而是有严格的区域划分!

想象一下,一个程序就像一栋大楼,不同楼层有不同功能:

  • 内核空间:大楼的顶层,操作系统用的,我们用户代码碰不到

  • 栈(Stack):像一个桶,从上面往下放东西(向下增长),放局部变量、函数参数

  • 内存映射段:中间层,用来加载动态库、文件映射,了解就行

  • 堆(Heap):像一个箱子,从下往上放东西(向上增长),我们手动申请的动态内存都在这

  • 数据段:放全局变量和静态变量,程序运行期间一直存在

  • 代码段:最底层,放我们写的代码(编译后的机器指令)和字符串常量

一张图让你秒懂:

新手必记口诀

  • 栈向下,堆向上,他俩对着长

  • 局部变量在栈上,动态申请在堆上

  • 全局静态数据段,代码常量代码段

2. 代码例子演示

【示例 1:不同变量的内存位置验证】

这个例子帮你直观感受不同变量存在哪里。

cpp 复制代码
#include <iostream>
using namespace std;

// 全局变量 - 数据段
int global_var = 100;

// 静态全局变量 - 数据段
static int static_global_var = 200;

void test(int param)  // param是函数参数 - 栈
{
    // 静态局部变量 - 数据段
    static int static_local_var = 300;
    
    // 局部变量 - 栈
    int local_var = 400;
    
    // 数组 - 栈
    int arr[5] = {1, 2, 3, 4, 5};
    
    // 字符串常量本身 - 代码段(常量区)
    // char2数组本身 - 栈
    char char2[] = "hello";
    
    // pChar3指针变量本身 - 栈
    // 指向的字符串"world" - 代码段(常量区)
    const char* pChar3 = "world";
    
    // ptr指针本身 - 栈
    // 指向的动态内存 - 堆
    int* ptr = (int*)malloc(sizeof(int) * 4);
    
    cout << "=== 各变量内存地址观察 ===" << endl;
    cout << "全局变量:        " << &global_var << endl;
    cout << "静态全局变量:    " << &static_global_var << endl;
    cout << "静态局部变量:    " << &static_local_var << endl;
    cout << "函数参数:        " << &param << endl;
    cout << "局部变量:        " << &local_var << endl;
    cout << "局部数组:        " << arr << endl;
    cout << "char2数组:       " << (void*)char2 << endl;
    cout << "pChar3指针本身:  " << (void*)&pChar3 << endl;
    cout << "pChar3指向内容:  " << (void*)pChar3 << endl;
    cout << "ptr指针本身:     " << (void*)&ptr << endl;
    cout << "ptr指向的堆内存: " << (void*)ptr << endl;
    
    free(ptr);
}

int main()
{
    test(666);
    return 0;
}

运行观察要点

  • 全局、静态变量的地址很接近,都在数据段

  • 局部变量、参数的地址也很接近,都在栈上(地址比较大)

  • malloc 出来的地址在另一个区域(堆)

  • 字符串常量 "world" 的地址很小,在代码段


例题练习:
cpp 复制代码
int globalVar = 1;
static int staticGlobalVar = 1;
void Test()
{
static int staticVar = 1;
int localVar = 1;
int num1[10] = { 1, 2, 3, 4 };
char char2[] = "abcd";
const char* pChar3 = "abcd";
int* ptr1 = (int*)malloc(sizeof(int) * 4);
int* ptr2 = (int*)calloc(4, sizeof(int));
int* ptr3 = (int*)realloc(ptr2, sizeof(int) * 4);
free(ptr1);
free(ptr3);
}
1. 选择题:
选项: A.栈  B.堆  C.数据段(静态区)  D.代码段(常量区)
globalVar在哪里?____   
staticGlobalVar在哪里?____
staticVar在哪里?____   
localVar在哪里?____
num1 在哪里?____
char2在哪里?____       
*char2在哪里?___
pChar3在哪里?____      
*pChar3在哪里?____
ptr1在哪里?____        
*ptr1在哪里?___

答案:

cpp 复制代码
答案及解析
1. C(数据段/静态区) ------ 全局变量默认存储在静态区,程序整个生命周期都存在。
2. C(数据段/静态区) ------ 静态全局变量同样存储在静态区,仅当前文件可见。
3. C(数据段/静态区) ------ 静态局部变量即使在函数内,也存储在静态区,只初始化一次,生命周期贯穿程序运行。
4. A(栈) ------ 普通局部变量,函数调用时在栈上分配,函数结束自动释放。
5. A(栈) ------ 局部数组属于局部变量,内存分配在栈上。
6. A(栈) ------ 局部数组名是栈上数组的首地址,数组整体存储在栈中。
7. A(栈) ------ 数组的第一个元素,和数组一起存储在栈中。
8. A(栈) ------ 指针变量本身是局部变量,存储在栈上。
9. D(代码段/常量区) ------ 指向的字符串常量`"abcd"`是只读常量,存储在常量区。
10.A(栈) ------ 指针变量本身是局部变量,存储在栈上。
11.B(堆) ------ `malloc`动态分配的内存,由程序员手动管理,存储在堆区。

(二)C 语言中的动态内存管理

C 语言提供了 4 个函数来管理动态内存:malloccallocreallocfree。记住:这四个函数都是在堆上操作的!

1. 基础概念解释

先给大家一个大白话总结:

|-------------|--------|-----------------|
| 函数 | 作用 | 特点 |
| malloc | 申请内存 | 只申请,不初始化,里面是垃圾值 |
| calloc | 申请内存 | 申请 + 自动初始化为 0 |
| realloc | 调整内存大小 | 对已有内存扩容 / 缩容 |
| free | 释放内存 | 把申请的内存还给系统 |

新手常见误区

  • ❌ 忘记 free → 内存泄漏

  • ❌ free 后继续使用指针 → 野指针

  • ❌ 重复 free 同一块内存 → 程序崩溃

  • ❌ free 不是 malloc 来的指针 → 程序崩溃

2. 代码例子演示

【示例 2:malloc 的基本用法】

malloc = memory + allocate,就是 "分配内存" 的意思。

cpp 复制代码
#include <iostream>
#include <stdlib.h>  // 要包含这个头文件!
using namespace std;

int main()
{
    cout << "=== malloc基本使用 ===" << endl;
    
    // 申请1个int的空间(4字节)
    // malloc返回void*,需要强转成我们需要的类型
    int* p1 = (int*)malloc(sizeof(int));
    
    // 【重要】malloc可能失败!一定要检查!
    if (p1 == NULL)
    {
        cout << "内存申请失败!" << endl;
        return -1;
    }
    
    // malloc申请的空间里是随机值(垃圾值)
    cout << "malloc后未初始化的值: " << *p1 << endl;
    
    // 我们自己赋值
    *p1 = 100;
    cout << "赋值后的值: " << *p1 << endl;
    
    // 申请10个int的空间(数组)
    int* p2 = (int*)malloc(sizeof(int) * 10);
    if (p2 != NULL)
    {
        // 像数组一样使用
        for (int i = 0; i < 10; i++)
        {
            p2[i] = i * 10;
        }
        
        cout << "malloc数组内容: ";
        for (int i = 0; i < 10; i++)
        {
            cout << p2[i] << " ";
        }
        cout << endl;
    }
    
    // 【重要】用完一定要释放!
    free(p1);
    free(p2);
    
    // 【好习惯】free后把指针置空,避免野指针
    p1 = NULL;
    p2 = NULL;
    
    cout << "内存已释放!" << endl;
    return 0;
}
【示例 3:calloc 的用法 - 自动初始化】

calloc 会把申请的内存自动清 0,懒人福音!

cpp 复制代码
#include <iostream>
#include <stdlib.h>
using namespace std;

int main()
{
    cout << "=== calloc的使用 ===" << endl;
    
    // calloc(个数, 每个的大小)
    // 申请5个int,每个自动初始化为0
    int* p = (int*)calloc(5, sizeof(int));
    
    if (p != NULL)
    {
        cout << "calloc自动初始化后的值: ";
        for (int i = 0; i < 5; i++)
        {
            cout << p[i] << " ";  // 输出: 0 0 0 0 0
        }
        cout << endl;
        
        // 当然我们也可以改值
        p[0] = 10;
        p[1] = 20;
        cout << "修改后的值: ";
        for (int i = 0; i < 5; i++)
        {
            cout << p[i] << " ";  // 输出: 10 20 0 0 0
        }
        cout << endl;
    }
    
    free(p);
    p = NULL;
    return 0;
}

malloc vs calloc 对比

  • malloc 更快,只申请不初始化

  • calloc 稍慢,但帮你清 0 了,更安全

【示例 4:realloc 的用法 - 调整内存大小】

realloc = re + allocate,就是 "重新分配"。比如原来申请了 4 个字节,现在不够用了,要变成 8 个字节。

cpp 复制代码
#include <iostream>
#include <stdlib.h>
using namespace std;

int main()
{
    cout << "=== realloc的使用 ===" << endl;
    
    // 先申请2个int空间
    int* p = (int*)malloc(sizeof(int) * 2);
    if (p == NULL) return -1;
    
    p[0] = 10;
    p[1] = 20;
    cout << "原来的空间(2个int): " << p[0] << " " << p[1] << endl;
    cout << "原来的地址: " << (void*)p << endl;
    
    // 不够用了!扩容到5个int
    int* new_p = (int*)realloc(p, sizeof(int) * 5);
    
    // 【重要】realloc可能返回新地址!
    // 所以要用新指针接收,不要直接覆盖p
    if (new_p != NULL)
    {
        p = new_p;  // 扩容成功,更新指针
        
        cout << "扩容后的地址: " << (void*)p << endl;
        cout << "扩容后原来的数据还在: " << p[0] << " " << p[1] << endl;
        
        // 新空间可以继续用
        p[2] = 30;
        p[3] = 40;
        p[4] = 50;
        
        cout << "扩容后全部数据: ";
        for (int i = 0; i < 5; i++)
        {
            cout << p[i] << " ";
        }
        cout << endl;
    }
    
    // realloc也可以缩小空间(不常用)
    p = (int*)realloc(p, sizeof(int) * 3);
    cout << "缩容后只剩3个空间了" << endl;
    
    free(p);
    p = NULL;
    return 0;
}

realloc 的两种情况

  1. 原地扩容:原来的空间后面还有空位,直接扩大,地址不变

  2. 异地扩容:原来的空间后面满了,找个新地方,把数据拷过去,释放旧空间,返回新地址


(三)C++ 中的内存管理(new、delete)

C 语言的内存管理在 C++ 中可以继续用,但 C++ 发明了更好用的:new 和 delete 操作符

1. 基础概念解释

为什么 C++ 要搞 new/delete?因为 C++ 有类啊!malloc 只会开空间,不会调用构造函数,这怎么行?

new 和 delete 的优势

  • ✅ 不用手动计算大小,自动算

  • ✅ 不用强转返回值,自动匹配类型

  • ✅ 可以初始化

  • ✅ 对自定义类型,自动调用构造 / 析构函数

  • ✅ 失败抛异常,不用判空(更现代的错误处理)

2. 代码例子演示

【示例 5:new、delete 操作内置类型】

先看对 int、double 这些基本类型怎么用。

cpp 复制代码
#include <iostream>
using namespace std;

int main()
{
    cout << "=== new/delete操作内置类型 ===" << endl;
    
    // 1. 申请单个int空间
    int* p1 = new int;
    *p1 = 100;
    cout << "单个int: " << *p1 << endl;
    delete p1;  // 释放
    
    // 2. 申请+初始化
    int* p2 = new int(200);  // 括号里是初始值
    cout << "申请+初始化: " << *p2 << endl;
    delete p2;
    
    // 3. 申请数组(10个int)
    int* p3 = new int[10];  // 中括号!
    for (int i = 0; i < 10; i++)
    {
        p3[i] = i * 10;
    }
    cout << "数组: ";
    for (int i = 0; i < 10; i++)
    {
        cout << p3[i] << " ";
    }
    cout << endl;
    delete[] p3;  // 【重要】数组要用delete[]!
    
    // 4. C++11新特性:数组初始化
    int* p4 = new int[5]{1, 2, 3, 4, 5};
    cout << "C++11数组初始化: ";
    for (int i = 0; i < 5; i++)
    {
        cout << p4[i] << " ";
    }
    cout << endl;
    delete[] p4;
    
    cout << "全部释放完成!" << endl;
    return 0;
}

重要提醒

  • new 单个对象 → delete

  • new 数组 → delete []

  • 一定要匹配使用! 不匹配会出问题!

【示例 6:new、delete 操作自定义类型】

这才是 new/delete 真正厉害的地方 ------ 自动调用构造 / 析构函数!

cpp 复制代码
#include <iostream>
using namespace std;

// 定义一个简单的类
class Person
{
public:
    // 构造函数
    Person(string name = "无名", int age = 0)
        : _name(name), _age(age)
    {
        cout << "构造函数调用: " << _name << "," << _age << "岁" << endl;
    }
    
    // 析构函数
    ~Person()
    {
        cout << "析构函数调用: " << _name << "拜拜了~" << endl;
    }
    
    void show()
    {
        cout << _name << "," << _age << "岁" << endl;
    }
    
private:
    string _name;
    int _age;
};

int main()
{
    cout << "===== 用malloc的情况 =====" << endl;
    // malloc只会开空间,不会调用构造函数!
    Person* p1 = (Person*)malloc(sizeof(Person));
    // p1指向的空间里是垃圾值,不是真正的对象!
    free(p1);  // free也不会调用析构函数!
    
    cout << endl << "===== 用new的情况 =====" << endl;
    // new = 开空间 + 调用构造函数
    Person* p2 = new Person("张三", 18);
    p2->show();
    // delete = 调用析构函数 + 释放空间
    delete p2;
    
    cout << endl << "===== new对象数组 =====" << endl;
    // new数组 = 开N个空间 + 调用N次构造函数
    Person* p3 = new Person[3]{
        Person("小明", 10),
        Person("小红", 11),
        Person("小刚", 12)
    };
    // delete[] = 调用N次析构函数 + 释放空间
    delete[] p3;
    
    return 0;
}

运行结果对比

cpp 复制代码
===== 用malloc的情况 =====

===== 用new的情况 =====
构造函数调用: 张三,18岁
张三,18岁
析构函数调用: 张三拜拜了~

===== new对象数组 =====
构造函数调用: 小明,10岁
构造函数调用: 小红,11岁
构造函数调用: 小刚,12岁
析构函数调用: 小刚拜拜了~
析构函数调用: 小红拜拜了~
析构函数调用: 小明拜拜了~
  • malloc/free:静悄悄,什么都不打印(没调用构造 / 析构)

  • new/delete:有构造有析构,对象真正被创建和销毁了

这就是为什么 C++ 推荐用 new/delete!因为我们要的是对象,不是一块光秃秃的内存!


(四)operator new 与 operator delete 函数

1. 基础概念解释

很多新手会搞混:new 和 operator new 不是一回事!

给大家理清楚:

  • new:是 C++ 的关键字(操作符),我们写代码用的

  • operator new:是一个全局函数,new 在底层会调用它

调用关系

cpp 复制代码
我们写 new Person 
    ↓ 底层调用
operator new函数 
    ↓ 底层调用
malloc函数

operator new 的作用

  • 本质就是封装了 malloc

  • malloc 失败返回 NULL,operator new 失败会抛异常(bad_alloc)

  • 这就是为什么 new 不需要判空的原因

同理:

  • delete 底层调用 operator delete

  • operator delete 底层调用 free

2. 代码例子演示

【示例 7:operator new/delete 的直接使用】

其实我们也可以直接调用这两个全局函数,虽然平时很少这么做。

cpp 复制代码
#include <iostream>
using namespace std;

class Test
{
public:
    Test() { cout << "构造函数" << endl; }
    ~Test() { cout << "析构函数" << endl; }
};

int main()
{
    cout << "===== operator new只开空间,不构造 =====" << endl;
    // operator new 只开空间,不调用构造函数!
    Test* p = (Test*)operator new(sizeof(Test));
    // 现在p指向的只是空间,还不是真正的对象!
    
    cout << "===== 手动调用构造函数(定位new) =====" << endl;
    // 如果要构造,需要手动调用
    new(p) Test;  // 定位new语法,在已有的空间上构造对象
    
    cout << "===== 手动调用析构函数 =====" << endl;
    p->~Test();  // 析构函数可以手动调用
    
    cout << "===== operator delete只释放空间,不析构 =====" << endl;
    operator delete(p);  // 只释放空间
    
    // 对比:new = operator new + 调用构造
    // delete = 调用析构 + operator delete
    
    return 0;
}

划重点

  • operator new = 只开空间(封装 malloc)

  • operator delete = 只释放空间(封装 free)

  • 真正的 new/delete,还要加上构造 / 析构的调用!


(五)new 与 delete 的实现原理

1. 基础概念解释

现在我们来揭开 new/delete 的神秘面纱,看看它到底是怎么工作的。

分两种情况:内置类型自定义类型

内置类型(int、double 等):
  • new:调用 operator new → 调用 malloc

  • delete:调用 operator delete → 调用 free

  • 其实和 malloc/free 差不多,只是错误处理方式不同

自定义类型(类对象):

new 的执行流程

  1. 调用 operator new 申请空间

  2. 在申请的空间上调用构造函数

  3. 返回对象的地址

delete 的执行流程

  1. 对对象调用析构函数

  2. 调用 operator delete 释放空间

new T [N] 数组的执行流程

  1. 调用 operator new [] → 调用 operator new → 调用 malloc

  2. 调用 N 次构造函数

  3. (偷偷多存了 4 字节,记录数组大小 N)

delete [ ] 的执行流程

  1. 从偷偷存的地方取出 N,调用 N 次析构函数

  2. 调用 operator delete [] → 调用 operator delete → 调用 free

2. 代码例子演示

【示例 8:new/delete 原理验证】

我们通过打印来观察调用顺序。

cpp 复制代码
#include <iostream>
using namespace std;

class MyClass
{
public:
    MyClass(int x = 0) : _x(x)
    {
        cout << "构造函数: x = " << _x << ", 地址: " << this << endl;
    }
    
    ~MyClass()
    {
        cout << "析构函数: x = " << _x << ", 地址: " << this << endl;
    }
    
private:
    int _x;
};

int main()
{
    cout << "========== 单个对象 new/delete ==========" << endl;
    cout << "准备new..." << endl;
    MyClass* p1 = new MyClass(100);
    cout << "new完成,准备delete..." << endl;
    delete p1;
    cout << "delete完成" << endl;
    
    cout << endl << "========== 数组 new[]/delete[] ==========" << endl;
    cout << "准备new[] 3个对象..." << endl;
    MyClass* p2 = new MyClass[3]{1, 2, 3};
    cout << "new[]完成,准备delete[]..." << endl;
    delete[] p2;
    cout << "delete[]完成" << endl;
    
    // 【错误示范】new[] 用 delete 释放(不用delete[])
    // cout << endl << "========== 错误示范!new[] 用 delete ==========" << endl;
    // MyClass* p3 = new MyClass[2]{10, 20};
    // delete p3;  // 只调用1次析构!内存泄漏!
    
    return 0;
}

运行观察

  • new 一个对象:先构造,返回地址

  • delete 一个对象:先析构,再释放

  • new [] 数组:3 次构造按顺序来

  • delete [] 数组:3 次析构按反序来(栈的特点)


(六)malloc/free 和 new/delete 的区别

1. 基础概念解释

这是面试必考题!我给大家整理了一张对比表,背下来面试直接满分!

|-----------|--------------|---------------------------|
| 对比维度 | malloc/free | new/delete |
| 身份 | C 语言的库函数 | C++ 的操作符(关键字) |
| 初始化 | 只申请空间,不初始化 | new 可以初始化(括号传参) |
| 大小计算 | 手动算字节数 | 自动计算(跟类型走) |
| 返回值 | void*,需要强转 | 直接返回对应类型指针 |
| 失败处理 | 返回 NULL,必须判空 | 抛异常 bad_alloc,需要捕获 |
| 自定义类型 | 只开空间,不调构造析构 | 开空间 + 调构造 / 析构 |
| 数组处理 | 手动计算大小 | new []/delete [] 专门处理 |
| 可重载吗? | 不能重载 | operator new/delete 可以重载 |
| 分配位置 | 堆 | 堆(自由存储区) |

一句话总结

  • malloc/free 是 C 语言的老古董,简单粗暴

  • new/delete 是 C++ 的升级版,专为面向对象设计,更安全更强大

2. 代码例子演示

【示例 9:对比演示 - 错误处理方式】
cpp 复制代码
#include <iostream>
#include <stdlib.h>
using namespace std;

int main()
{
    cout << "===== malloc失败返回NULL =====" << endl;
    // 申请一个超大空间,故意让它失败
    int* p1 = (int*)malloc(1024 * 1024 * 1024 * 100);  // 100GB!
    if (p1 == NULL)
    {
        cout << "malloc失败了!返回NULL" << endl;
    }
    else
    {
        free(p1);
    }
    
    cout << endl << "===== new失败抛异常 =====" << endl;
    try
    {
        // 同样申请超大空间
        int* p2 = new int[1024 * 1024 * 1024 * 100];
        // 如果成功才会走到这
        delete[] p2;
    }
    catch (const bad_alloc& e)
    {
        cout << "new失败了!抛出异常: " << e.what() << endl;
    }
    
    cout << endl << "程序正常结束~" << endl;
    return 0;
}

总结

今天的内容有点多,给大家划个重点:

  1. 内存分布:栈向下,堆向上,全局静态数据段,代码常量代码段

  2. C 语言四件套:malloc(申请)、calloc(申请 + 清 0)、realloc(调整)、free(释放)

  3. C++ 新方式:new/delete,比 C 的好用,支持自定义类型

  4. 底层原理:new 底层调用 operator new,operator new 底层调用 malloc

  5. 面试必背:malloc 和 new 的 6 大区别

新手建议

  • C++ 中尽量用 new/delete,少用 malloc/free

  • 一定要记得释放内存!养成好习惯

  • new 和 delete 要匹配,new [] 和 delete [] 要匹配


下期预告

下一篇我们来讲讲C++ 模板,初步了解STL

好啦,如果你想了解更多C++的内容记得关注我哦,【从零开始学 C++】系列持续更新中!

如果这篇文章对你有帮助,别忘了点赞 + 收藏 + 评论三连!有问题评论区见~

相关推荐
ooseabiscuit1 小时前
Laravel6.x核心优化与特性全解析
android·开发语言·javascript
折哥的程序人生 · 物流技术专研1 小时前
Java面试85题图解版(一):基础核心篇
java·开发语言·后端·面试
Hello.Reader2 小时前
算法基础(十)——分治思想把大问题拆成小问题
java·开发语言·算法
一只大袋鼠2 小时前
JavaWeb四种文件上传方式(下篇)
java·开发语言·springmvc·javaweb
TE-茶叶蛋2 小时前
深入研究 yudao-framework 模块:Java 编程能力提升指南
java·开发语言
CHANG_THE_WORLD2 小时前
C语言中的 %*s 和 %.*s 和C++的字符串格式化输出
c语言·c++·c#
逻辑驱动的ken2 小时前
Java高频考点场景题24
java·开发语言·面试·职场和发展·求职招聘
兔小盈3 小时前
多线程-(五)线程安全之内存可见性
java·开发语言·多线程
yaoxin5211233 小时前
400. Java 文件操作基础 - 使用 Buffered Stream I/O 读取文本文件
java·开发语言·python