C++ 动态数组
外观
C++动态数组[编辑 | 编辑源代码]
动态数组是C++中一种在运行时动态分配内存的数组结构,它允许程序在需要时灵活地调整存储空间大小。与静态数组不同,动态数组的大小不需要在编译时确定,而是可以根据程序运行时的需求进行扩展或收缩。
基本概念[编辑 | 编辑源代码]
在C++中,动态数组主要通过指针和内存管理操作符(new
和delete
)实现。动态数组的核心优势在于其灵活性,但同时也要求程序员手动管理内存以避免内存泄漏。
静态数组 vs 动态数组[编辑 | 编辑源代码]
特性 | 静态数组 | 动态数组 |
---|---|---|
内存分配时间 | 编译时 | 运行时 |
大小 | 固定 | 可变 |
内存管理 | 自动 | 手动 |
创建动态数组[编辑 | 编辑源代码]
使用new[]
操作符分配内存,delete[]
释放内存:
// 创建动态数组
int size = 5;
int* dynamicArray = new int[size]; // 分配5个整数的空间
// 初始化数组
for (int i = 0; i < size; ++i) {
dynamicArray[i] = i * 10;
}
// 使用数组
for (int i = 0; i < size; ++i) {
std::cout << dynamicArray[i] << " ";
}
// 输出: 0 10 20 30 40
// 释放内存
delete[] dynamicArray;
调整数组大小[编辑 | 编辑源代码]
动态数组可以通过以下步骤调整大小: 1. 分配新内存块 2. 复制旧数据 3. 释放旧内存
// 原始数组
int* arr = new int[3]{1, 2, 3};
// 调整大小到5
int* newArr = new int[5];
for (int i = 0; i < 3; ++i) {
newArr[i] = arr[i];
}
delete[] arr;
arr = newArr;
// 添加新元素
arr[3] = 4;
arr[4] = 5;
二维动态数组[编辑 | 编辑源代码]
创建二维动态数组需要分配指针数组,然后为每行分配内存:
int rows = 3, cols = 4;
int** matrix = new int*[rows];
for (int i = 0; i < rows; ++i) {
matrix[i] = new int[cols];
}
// 使用后需要逐行释放
for (int i = 0; i < rows; ++i) {
delete[] matrix[i];
}
delete[] matrix;
常见问题[编辑 | 编辑源代码]
内存泄漏[编辑 | 编辑源代码]
忘记释放动态数组会导致内存泄漏:
int* leakyArray = new int[100];
// 忘记调用 delete[] leakyArray;
悬垂指针[编辑 | 编辑源代码]
释放内存后继续使用指针:
int* ptr = new int[10];
delete[] ptr;
ptr[0] = 1; // 未定义行为!
实际应用案例[编辑 | 编辑源代码]
游戏开发中的实体管理系统常使用动态数组存储游戏实体,因为实体数量在运行时可能变化:
class GameEntity {
// 实体属性和方法
};
class EntityManager {
GameEntity** entities;
int capacity;
int count;
public:
EntityManager(int initialCapacity = 10)
: capacity(initialCapacity), count(0) {
entities = new GameEntity*[capacity];
}
~EntityManager() {
for (int i = 0; i < count; ++i) {
delete entities[i];
}
delete[] entities;
}
void addEntity(GameEntity* entity) {
if (count == capacity) {
// 扩容
capacity *= 2;
GameEntity** newEntities = new GameEntity*[capacity];
for (int i = 0; i < count; ++i) {
newEntities[i] = entities[i];
}
delete[] entities;
entities = newEntities;
}
entities[count++] = entity;
}
};
性能考虑[编辑 | 编辑源代码]
动态数组操作的时间复杂度:
- 访问元素:O(1)
- 插入/删除末尾元素:O(1)(不考虑扩容)
- 插入/删除中间元素:O(n)
- 扩容操作:O(n)
内存布局示意图:
数学表示[编辑 | 编辑源代码]
动态数组的内存分配可以表示为: 其中:
- 是总内存需求
- 是元素数量
- 是单个元素大小
最佳实践[编辑 | 编辑源代码]
1. 总是配对使用new[]
和delete[]
2. 考虑使用RAII技术管理内存
3. 对于复杂项目,优先使用标准库容器如std::vector
4. 在调整大小时,采用几何增长策略(如每次扩容为原来的2倍)以减少频繁重新分配
总结[编辑 | 编辑源代码]
动态数组是C++内存管理的基础概念,提供了运行时灵活分配内存的能力。虽然手动管理动态数组有助于理解内存工作原理,但在实际项目中应优先考虑使用标准库提供的容器类,它们更安全且功能更丰富。