跳转到内容

C++ 动态数组

来自代码酷

C++动态数组[编辑 | 编辑源代码]

动态数组是C++中一种在运行时动态分配内存的数组结构,它允许程序在需要时灵活地调整存储空间大小。与静态数组不同,动态数组的大小不需要在编译时确定,而是可以根据程序运行时的需求进行扩展或收缩。

基本概念[编辑 | 编辑源代码]

在C++中,动态数组主要通过指针和内存管理操作符(newdelete)实现。动态数组的核心优势在于其灵活性,但同时也要求程序员手动管理内存以避免内存泄漏。

静态数组 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)

内存布局示意图:

graph LR A[指针] --> B[连续内存块] B --> C[元素0] B --> D[元素1] B --> E[...] B --> F[元素n-1]

数学表示[编辑 | 编辑源代码]

动态数组的内存分配可以表示为: M=n×s 其中:

  • M是总内存需求
  • n是元素数量
  • s是单个元素大小

最佳实践[编辑 | 编辑源代码]

1. 总是配对使用new[]delete[] 2. 考虑使用RAII技术管理内存 3. 对于复杂项目,优先使用标准库容器如std::vector 4. 在调整大小时,采用几何增长策略(如每次扩容为原来的2倍)以减少频繁重新分配

总结[编辑 | 编辑源代码]

动态数组是C++内存管理的基础概念,提供了运行时灵活分配内存的能力。虽然手动管理动态数组有助于理解内存工作原理,但在实际项目中应优先考虑使用标准库提供的容器类,它们更安全且功能更丰富。