📚 动态内存管理概述
为什么需要动态内存?
在程序运行时,有时我们无法预先知道需要多少内存。动态内存分配允许我们在运行时根据需要申请和释放内存。
- ✅ 灵活性强:根据实际需求分配内存
- ✅ 节省空间:避免浪费不必要的内存
- ✅ 生命周期可控:手动管理内存的创建和销毁
- ✅ 数据结构基础:链表、树等动态结构的核心
💡 内存区域对比:
• 栈(Stack):自动管理,函数结束时释放
• 堆(Heap):手动管理,需要new/delete
• 动态内存在堆上分配
new和delete运算符
#include <iostream>
using namespace std;
int main() {
int* ptr = new int;
*ptr = 42;
cout << "*ptr = " << *ptr << endl;
int* ptr2 = new int(100);
cout << "*ptr2 = " << *ptr2 << endl;
delete ptr;
delete ptr2;
ptr = nullptr;
ptr2 = nullptr;
return 0;
}
动态数组
#include <iostream>
using namespace std;
int main() {
int size;
cout << "输入数组大小:";
cin >> size;
int* arr = new int[size];
for (int i = 0; i < size; i++) {
arr[i] = i * 10;
}
for (int i = 0; i < size; i++) {
cout << arr[i] << " ";
}
cout << endl;
delete[] arr;
arr = nullptr;
return 0;
}
⚠️ 重要提醒:
• 单个对象用 delete
• 数组用 delete[]
• 忘记释放会导致内存泄漏
• 释放后设置为 nullptr 避免野指针
⚙️ 指针数组和数组指针
指针数组
#include <iostream>
using namespace std;
int main() {
int a = 10, b = 20, c = 30;
int* ptrArray[3] = {&a, &b, &c};
for (int i = 0; i < 3; i++) {
cout << "*ptrArray[" << i << "] = " << *ptrArray[i] << endl;
}
const char* fruits[] = {"Apple", "Banana", "Cherry"};
for (int i = 0; i < 3; i++) {
cout << fruits[i] << endl;
}
return 0;
}
二级指针的应用
#include <iostream>
using namespace std;
int** createMatrix(int rows, int cols) {
int** matrix = new int*[rows];
for (int i = 0; i < rows; i++) {
matrix[i] = new int[cols];
}
return matrix;
}
void deleteMatrix(int** matrix, int rows) {
for (int i = 0; i < rows; i++) {
delete[] matrix[i];
}
delete[] matrix;
}
int main() {
int rows = 3, cols = 4;
int** matrix = createMatrix(rows, cols);
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
matrix[i][j] = i * cols + j;
}
}
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
cout << matrix[i][j] << "\t";
}
cout << endl;
}
deleteMatrix(matrix, rows);
return 0;
}
动态结构体
#include <iostream>
#include <string>
using namespace std;
struct Student {
string name;
int age;
double score;
};
int main() {
Student* stu = new Student;
stu->name = "张三";
stu->age = 18;
stu->score = 95.5;
cout << "姓名:" << stu->name << endl;
cout << "年龄:" << stu->age << endl;
cout << "成绩:" << stu->score << endl;
delete stu;
stu = nullptr;
return 0;
}
🎮 互动实验:动态数组演示
输入数组大小,观察动态内存分配过程
输入大小后点击按钮...
🛠️ 智能指针简介
为什么需要智能指针?
手动管理内存容易出错:内存泄漏(忘记delete)、野指针(重复delete)、悬空指针(访问已释放的内存)。智能指针可以自动管理内存,避免这些问题。
💡 C++11引入的智能指针:
• unique_ptr - 独占所有权
• shared_ptr - 共享所有权(引用计数)
• weak_ptr - 弱引用(配合shared_ptr使用)
unique_ptr(独占指针)
#include <iostream>
#include <memory>
using namespace std;
int main() {
unique_ptr<int> ptr1(new int(42));
cout << "*ptr1 = " << *ptr1 << endl;
unique_ptr<int> ptr2 = move(ptr1);
if (ptr1 == nullptr) {
cout << "ptr1已为空" << endl;
}
cout << "*ptr2 = " << *ptr2 << endl;
return 0;
}
shared_ptr(共享指针)
#include <iostream>
#include <memory>
using namespace std;
int main() {
shared_ptr<int> ptr1 = make_shared<int>(42);
cout << "*ptr1 = " << *ptr1 << endl;
cout << "引用计数:" << ptr1.use_count() << endl;
shared_ptr<int> ptr2 = ptr1;
cout << "引用计数:" << ptr1.use_count() << endl;
cout << "引用计数:" << ptr2.use_count() << endl;
return 0;
}
智能指针的实际应用
#include <iostream>
#include <memory>
#include <vector>
using namespace std;
struct Student {
string name;
int age;
Student(const string& n, int a) : name(n), age(a) {
cout << "创建学生:" << name << endl;
}
~Student() {
cout << "销毁学生:" << name << endl;
}
};
int main() {
vector<shared_ptr<Student>> students;
students.push_back(make_shared<Student>("张三", 18));
students.push_back(make_shared<Student>("李四", 19));
students.push_back(make_shared<Student>("王五", 20));
for (const auto& stu : students) {
cout << stu->name << ", " << stu->age << "岁" << endl;
}
return 0;
}
🚀 高级指针技术
内存泄漏检测
#include <iostream>
using namespace std;
void memoryLeakExample() {
int* ptr = new int(42);
}
void correctExample() {
int* ptr = new int(42);
cout << "*ptr = " << *ptr << endl;
delete ptr;
ptr = nullptr;
}
void smartPointerExample() {
unique_ptr<int> ptr(new int(42));
}
int main() {
correctExample();
smartPointerExample();
cout << "没有内存泄漏!" << endl;
return 0;
}
实际应用:动态链表
#include <iostream>
#include <memory>
using namespace std;
struct Node {
int data;
shared_ptr<Node> next;
Node(int val) : data(val), next(nullptr) {}
};
class LinkedList {
private:
shared_ptr<Node> head;
public:
LinkedList() : head(nullptr) {}
void insertFront(int value) {
auto newNode = make_shared<Node>(value);
newNode->next = head;
head = newNode;
}
void printList() {
auto current = head;
while (current != nullptr) {
cout << current->data << " -> ";
current = current->next;
}
cout << "NULL" << endl;
}
};
int main() {
LinkedList list;
list.insertFront(3);
list.insertFront(2);
list.insertFront(1);
cout << "链表:";
list.printList();
return 0;
}
📝 实战练习
📝 理解测试
以下代码有什么问题?
#include <iostream>
using namespace std;
int main() {
int* arr = new int[10];
delete arr;
return 0;
}
选择答案查看解析...
💻 综合挑战
题目:编写一个程序,实现动态数组类:
1. 可以动态调整数组大小
2. 支持添加、删除元素
3. 自动管理内存(或使用智能指针)
4. 提供打印数组的功能
点击"生成代码框架"查看提示...