好的,我们来详细讲解 C/C++ 数据结构中的动态数组(Dynamic Array),这是数据结构中非常重要的一部分,尤其在对内存管理和性能有要求的 C/C++ 开发中。
📚 目录
- 什么是动态数组?
- 静态数组 vs 动态数组
- C 语言中的动态数组实现
- C++ 中的
vector
封装 - 实现原理:扩容与缩容机制
- 动态数组操作(增、删、改、查)
- 手动实现一个简易动态数组(C代码)
- 动态数组的使用场景与注意事项
- 参考资料
1. 什么是动态数组?
动态数组是一种可以在运行时改变其大小的数组结构。
- 在 静态数组 中,我们必须在编译时指定数组大小。
- 动态数组 可以随着元素的添加或删除自动调整容量。
2. 静态数组 vs 动态数组
特性 | 静态数组 | 动态数组 |
---|---|---|
内存分配方式 | 编译时 | 运行时(heap) |
数组大小是否固定 | 是 | 否,可扩容/缩容 |
灵活性 | 差 | 高 |
控制权 | 程序员无法更改大小 | 程序员控制 realloc |
3. C语言中动态数组的实现(使用 malloc/realloc)
#include <stdio.h>
#include <stdlib.h>
int main() {
int *arr = NULL;
int capacity = 2;
int size = 0;
arr = (int*) malloc(capacity * sizeof(int));
if (!arr) {
perror("malloc failed");
return 1;
}
// 添加元素
for (int i = 0; i < 10; ++i) {
if (size >= capacity) {
capacity *= 2;
arr = (int*) realloc(arr, capacity * sizeof(int));
if (!arr) {
perror("realloc failed");
return 1;
}
}
arr[size++] = i * 10;
}
// 打印
for (int i = 0; i < size; ++i) {
printf("%d ", arr[i]);
}
free(arr);
return 0;
}
4. C++ 中的动态数组封装:std::vector
C++ 提供了更安全、更强大的封装 —— std::vector
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> v;
// 添加元素
for (int i = 0; i < 10; ++i)
v.push_back(i * 10);
// 访问
for (int i = 0; i < v.size(); ++i)
cout << v[i] << " ";
return 0;
}
🔹 自动管理内存
🔹 支持迭代器
🔹 支持动态扩容和缩容
5. 动态数组的扩容与缩容机制
动作 | 实现方式 |
---|---|
扩容 | capacity *= 2 |
缩容 | capacity /= 2 (可选) |
realloc | 重新分配更大/更小的内存空间,拷贝数据到新空间 |
6. 动态数组的常见操作
操作 | 方法 | 描述 |
---|---|---|
增加元素 | push_back / insert | 在末尾添加 |
删除元素 | pop_back / erase | 删除末尾或指定位置 |
查找元素 | [] / at() | 访问下标元素 |
修改元素 | arr[i] = newVal; | 修改值 |
7. 手动实现一个简易动态数组结构(C语言封装版)
typedef struct {
int *data;
int size;
int capacity;
} DynamicArray;
void init(DynamicArray *a, int initCap) {
a->data = (int*) malloc(initCap * sizeof(int));
a->size = 0;
a->capacity = initCap;
}
void push_back(DynamicArray *a, int value) {
if (a->size >= a->capacity) {
a->capacity *= 2;
a->data = (int*) realloc(a->data, a->capacity * sizeof(int));
}
a->data[a->size++] = value;
}
void freeArray(DynamicArray *a) {
free(a->data);
a->size = a->capacity = 0;
}
8. 动态数组的使用场景与注意事项
✅ 适用场景:
- 不确定元素数量时(用户输入、读取文件等)
- 想要按需动态扩容的数据结构
- 性能敏感场景(避免链表频繁分配)
⚠️ 注意事项:
realloc
后必须检查指针是否为 NULL- 内存泄漏风险(记得
free
) - 多线程场景下需加锁保护
发表回复