C++ 内存分配详解

内存分配是C++编程中的核心概念,主要分为栈分配堆分配两种方式。

1. 栈内存分配(自动分配)

栈内存由编译器自动管理,分配和释放速度快。
特点:

  • 自动分配和释放
  • 大小有限(通常几MB)
  • 局部变量存储在栈上
  • 函数结束时自动释放
cpp 复制代码
#include <iostream>
using namespace std;

void stackExample() {
    int x = 10;              // 栈上分配
    int arr[100];            // 栈上分配数组(大小固定)
    double d = 3.14;
    
    // 函数结束时,所有局部变量自动释放
}

int main() {
    stackExample();
    return 0;
}

2. 堆内存分配(动态分配)

堆内存由程序员手动管理,使用 newdelete 操作符。
特点:

  • 手动分配和释放
  • 内存较大(受系统限制)
  • 生命周期由程序员控制
  • 分配速度较慢

3. new 和 delete 的基本用法

分配单个变量

cpp 复制代码
// 分配内存
int *p = new int;     // 分配一个int类型的内存
*p = 42;              // 向分配的内存写入值

// 分配并初始化
int *p2 = new int(100);  // 直接初始化为100

// 释放内存
delete p;
delete p2;
p = nullptr;  // 好习惯:释放后置为空指针
p2 = nullptr;

分配数组

cpp 复制代码
// 分配数组
int size = 10;
int *arr = new int[size];  // 分配10个int的数组

// 初始化数组
for (int i = 0; i < size; i++) {
    arr[i] = i * 10;
}

// 释放数组内存(必须使用 delete[])
delete[] arr;
arr = nullptr;

4. new 的高级用法

初始化数组(C++11及以上)

cpp 复制代码
// 使用初始化列表
int *arr1 = new int[5]{1, 2, 3, 4, 5};

// 默认初始化(所有元素为0)
int *arr2 = new int[5]();  // 所有元素初始化为0

// 分配并初始化字符串
char *str = new char[10]{'H', 'e', 'l', 'l', 'o', '\0'};

分配多维数组

cpp 复制代码
// 方法1:使用一维数组模拟
int rows = 3, cols = 4;
int *matrix = new int[rows * cols];
// 访问元素:matrix[i * cols + j]

// 方法2:指针数组(更直观但需要多层释放)
int **matrix2 = new int*[rows];
for (int i = 0; i < rows; i++) {
    matrix2[i] = new int[cols];
}

// 使用
for (int i = 0; i < rows; i++) {
    for (int j = 0; j < cols; j++) {
        matrix2[i][j] = i * j;
    }
}

// 释放多维数组
for (int i = 0; i < rows; i++) {
    delete[] matrix2[i];
}
delete[] matrix2;
matrix2 = nullptr;

5. 内存分配失败处理

传统方式(抛出异常)

cpp 复制代码
try {
    int *p = new int[1000000000000];  // 分配过大的内存
    delete[] p;
} catch (const std::bad_alloc& e) {
    cout << "内存分配失败: " << e.what() << endl;
}

使用 std::nothrow(不抛出异常)

cpp 复制代码
int *p = new(std::nothrow) int[1000000000000];
if (p == nullptr) {
    cout << "内存分配失败" << endl;
    // 处理错误
} else {
    delete[] p;
}

6. 动态分配对象

单个对象

cpp 复制代码
class MyClass {
public:
    int value;
    MyClass(int v) : value(v) {
        cout << "构造函数: " << value << endl;
    }
    ~MyClass() {
        cout << "析构函数: " << value << endl;
    }
};

int main() {
    // 动态创建对象
    MyClass *obj = new MyClass(42);
    
    // 使用对象
    cout << "对象值: " << obj->value << endl;
    
    // 手动释放
    delete obj;
    obj = nullptr;
    
    return 0;
}

7. 内存分配的最佳实践

1. 总是检查分配是否成功

cpp 复制代码
int *p = new(std::nothrow) int[1000];
if (!p) {
    // 处理内存不足的情况
    cerr << "内存不足!" << endl;
    return -1;
}

2. 配对使用 new/deletenew[]/delete[]

cpp 复制代码
// 正确
int *single = new int;
delete single;

int *array = new int[10];
delete[] array;  // 注意是 delete[]

// 错误
int *arr = new int[10];
delete arr;      // 错误!应该使用 delete[]

3. 避免内存泄漏

cpp 复制代码
void badFunction() {
    int *p = new int[100];
    // 忘记 delete[] p;  // 内存泄漏!
}

void goodFunction() {
    int *p = new int[100];
    // 使用内存...
    delete[] p;  // 正确释放
    p = nullptr;
}

4. 使用 RAII(Resource Acquisition Is Initialization)

cpp 复制代码
class SmartArray {
private:
    int *data;
    int size;
public:
    SmartArray(int n) : size(n) {
        data = new int[n];
    }
    
    ~SmartArray() {
        delete[] data;
        data = nullptr;
    }
    
    // 禁用拷贝构造和赋值(或实现深拷贝)
    SmartArray(const SmartArray&) = delete;
    SmartArray& operator=(const SmartArray&) = delete;
    
    // 移动语义
    SmartArray(SmartArray&& other) noexcept
        : data(other.data), size(other.size) {
        other.data = nullptr;
        other.size = 0;
    }
};

int main() {
    SmartArray arr(100);  // 自动管理内存
    // 函数结束时自动调用析构函数释放内存
    return 0;
}
相关推荐
散峰而望5 小时前
【算法竞赛】C++函数详解:从定义、调用到高级用法
c语言·开发语言·数据结构·c++·算法·github
冷凝雨6 小时前
复数乘法(C & Simulink)
c语言·开发语言·信号处理·simulink·dsp
CoderCodingNo6 小时前
【GESP】C++五级真题(贪心思想考点) luogu-B4071 [GESP202412 五级] 武器强化
开发语言·c++·算法
我有一些感想……6 小时前
An abstract way to solve Luogu P1001
c++·算法·ai·洛谷·mlp
0和1的舞者6 小时前
Spring AOP详解(一)
java·开发语言·前端·spring·aop·面向切面
MoonBit月兔6 小时前
年终 Meetup:走进腾讯|AI 原生编程与 Code Agent 实战交流会
大数据·开发语言·人工智能·腾讯云·moonbit
智航GIS6 小时前
8.2 面向对象
开发语言·python
小小星球之旅6 小时前
CompletableFuture学习
java·开发语言·学习
智者知已应修善业7 小时前
【求等差数列个数/无序获取最大最小次大次小】2024-3-8
c语言·c++·经验分享·笔记·算法
kylezhao20197 小时前
C# 语言基础(变量、数据类型、流程控制、面向对象编程)
开发语言·计算机视觉·c#·visionpro