跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
代码酷
搜索
搜索
中文(中国大陆)
外观
创建账号
登录
个人工具
创建账号
登录
未登录编辑者的页面
了解详情
贡献
讨论
编辑“︁
C++ 动态内存分配
”︁
页面
讨论
大陆简体
阅读
编辑
编辑源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
编辑
编辑源代码
查看历史
常规
链入页面
相关更改
特殊页面
页面信息
外观
移至侧栏
隐藏
您的更改会在有权核准的用户核准后向读者展示。
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
= C++动态内存分配 = '''动态内存分配'''是C++中一种在程序运行时(而非编译时)请求和释放内存的机制。它允许程序根据需要灵活地管理内存,特别适合处理未知大小的数据结构或需要长时间保留的数据。 == 基本概念 == 在C++中,动态内存分配主要通过<code>new</code>和<code>delete</code>运算符实现: * '''new''':在堆(heap)上分配内存并返回指向该内存的指针 * '''delete''':释放先前通过<code>new</code>分配的内存 === 与静态内存分配的区别 === {| class="wikitable" |- ! 特性 !! 静态内存分配 !! 动态内存分配 |- | 分配时间 || 编译时 || 运行时 |- | 内存来源 || 栈(Stack) || 堆(Heap) |- | 大小 || 固定 || 可变 |- | 生命周期 || 作用域内 || 直到显式释放 |} == 基本用法 == === 单个对象的分配与释放 === <syntaxhighlight lang="cpp"> // 分配一个int类型的内存 int* ptr = new int; // 赋值 *ptr = 42; // 使用 std::cout << "Value: " << *ptr << std::endl; // 释放内存 delete ptr; ptr = nullptr; // 避免悬空指针 </syntaxhighlight> '''输出''': <pre> Value: 42 </pre> === 数组的分配与释放 === <syntaxhighlight lang="cpp"> // 分配包含5个int的数组 int* arr = new int[5]; // 初始化数组 for (int i = 0; i < 5; ++i) { arr[i] = i * 10; } // 使用数组 for (int i = 0; i < 5; ++i) { std::cout << arr[i] << " "; } // 释放数组内存 delete[] arr; arr = nullptr; </syntaxhighlight> '''输出''': <pre> 0 10 20 30 40 </pre> == 内存管理图例 == <mermaid> graph LR A[程序] --> B[栈内存 Stack] A --> C[堆内存 Heap] B --> D[自动管理] C --> E[手动管理 new/delete] </mermaid> == 常见问题与最佳实践 == === 内存泄漏 === 忘记释放动态分配的内存会导致内存泄漏: <syntaxhighlight lang="cpp"> void leakMemory() { int* ptr = new int(100); // 内存泄漏 - 没有对应的delete } </syntaxhighlight> '''解决方案''': * 使用智能指针(C++11及以上) * 遵循RAII(资源获取即初始化)原则 === 悬空指针 === 访问已释放的内存: <syntaxhighlight lang="cpp"> int* ptr = new int(50); delete ptr; *ptr = 60; // 未定义行为 - ptr现在是悬空指针 </syntaxhighlight> '''解决方案''': * 释放后立即将指针设为<code>nullptr</code> * 使用智能指针 === 智能指针(C++11及以上) === 现代C++推荐使用智能指针自动管理内存: <syntaxhighlight lang="cpp"> #include <memory> void safeMemory() { std::unique_ptr<int> ptr = std::make_unique<int>(42); // 不需要手动delete - 超出作用域时自动释放 std::cout << *ptr << std::endl; } </syntaxhighlight> == 实际应用案例 == === 动态数据结构 === 动态内存分配在实现链表、树等数据结构时必不可少: <syntaxhighlight lang="cpp"> struct Node { int data; Node* next; }; Node* createList(int size) { Node* head = nullptr; Node** current = &head; for (int i = 0; i < size; ++i) { *current = new Node{i, nullptr}; current = &((*current)->next); } return head; } void deleteList(Node* head) { while (head != nullptr) { Node* temp = head; head = head->next; delete temp; } } </syntaxhighlight> === 大型数据处理 === 处理未知大小的数据集: <syntaxhighlight lang="cpp"> double* readDataFromFile(const std::string& filename, int& count) { std::ifstream file(filename); std::vector<double> temp; double value; while (file >> value) { temp.push_back(value); } count = temp.size(); double* data = new double[count]; std::copy(temp.begin(), temp.end(), data); return data; } </syntaxhighlight> == 数学表达 == 动态内存分配的内存消耗可以表示为: <math> M_{\text{total}} = \sum_{i=1}^{n} (S_i + O_{\text{overhead}}) </math> 其中: * <math>M_{\text{total}}</math>是总内存消耗 * <math>S_i</math>是第i次分配的大小 * <math>O_{\text{overhead}}</math>是内存分配器的开销 == 性能考虑 == 动态内存分配比栈分配慢,因为: * 需要查找合适的空闲内存块 * 可能触发操作系统调用 * 可能导致内存碎片 '''优化建议''': * 预分配大块内存 * 使用内存池 * 尽可能重用已分配的内存 == 总结表 == {| class="wikitable" |- ! 操作 !! 语法 !! 说明 |- | 单个对象分配 || <code>new Type</code> || 分配单个对象 |- | 数组分配 || <code>new Type[size]</code> || 分配数组 |- | 单个对象释放 || <code>delete ptr</code> || 释放单个对象 |- | 数组释放 || <code>delete[] arr</code> || 释放数组 |- | 初始化分配 || <code>new Type(value)</code> || 分配并初始化 |} [[Category:编程语言]] [[Category:C++]] [[Category:C++ 内存管理]]
摘要:
请注意,所有对代码酷的贡献均被视为依照知识共享署名-非商业性使用-相同方式共享发表(详情请见
代码酷:著作权
)。如果您不希望您的文字作品被随意编辑和分发传播,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)