1.内存模型
·栈(Stack):
用于静态内存分配 自动管理内存 当函数调用结束时 栈上的内存会被自动释放
·堆(Heap):
用于动态内存分配 需要手动管理 通过new、delete 等语句进行操作 在程序运行时 可以根据需要分配和释放内存
·全局/静态区:
用于全局变量和静态变量的存储 程序结束时自动释放
·代码区:
存储程序的指令和常量
2.动态内存分配
在C++中 动态内存分配主要使用以下关键字:
new:同于在堆上分配内存
·单个对象:
int *p = new int; //分配一个整数
· 数组:
int* arr = new int[10]; //分配一个整数数组
new[ ]:用于动态分配数组 创建多个相同类型的对象
3.内存释放:
动态分配的内存需要手动释放 以防止内存泄漏 使用以下关键字:
delete:释放由new分配的单个对象
delete p; //释放单个整数
delete[ ]:释放由new[ ]分配的数组
delete[] arr; //释放整数数组
4.内存泄漏
定义:
内存泄漏是指程序在动态分配内存后 没有释放相应的内存 从而导致该内存块变得 不可用 最终可能导致系统可用内存不足
原因:
忘记释放内存:使用new分配内存 但没有调用delete释放
异常处理:在分配内存后 如果抛出异常而没有进行清理操作
多个指针:多个指针指向同一块内存 某个指针被释放后 其他指针仍然指向已释放的内存
预防措施:
确保每次new后都有对应的delete
使用智能指针 如 unique_ptr 和 shared_ptr 他们会自动管理内存 避免泄露
定期使用内存分析工具(如Valgrind)来检测内存泄漏
野指针:
定义:
野指针是指向已经释放或未初始化内存地址的指针 访问野指针所指向的内存将导致未定义行为 可能引起程序崩溃或数据损坏
原因:
指针未初始化:指针在使用前没有被正确初始化
指针被释放后继续使用:在删除或释放一个指针后 仍然试图访问它
错误的内存操作:例如 数组越界或错误的类型转换
预防措施:
在释放指针之后 将其设置为 nullptr
使用智能指针 避免手动管理内存
初始化所有指针变量 在声明时将其设为 nullptr
5.智能指针
使用智能指针可以自动管理内存 减少内存泄漏的风险 C++11引入了三种智能指针
unique_ptr:
独占所有权 只能有一个指针指向该内存 超出作用域即释放
#include<iostream>
using namespace std;
void uniqueptr() {
//创建一个unique_ptr 管理一个int类型的动态内存
unique_ptr<int> ptr(new int(10));
//使用智能指针
cout << *ptr << endl;
//不需要手动delete 离开作用域时自动释放内存
}
int main() {
uniqueptr();
return 0;
}
shared_ptr:
共享所有权 允许多个指针共同拥有同一内存 引用计数管理
引用计数:
工作原理:
初始化:当创建一个共享资源时 引用计数初始化为1
复制:每当一个新的指针(如:shared_ptr)共享同一个资源时引用计数加1
销毁:当一个指针被销毁或重新赋值 引用计数减1
释放:当引用计数为0时 表示没有指针再使用这个资源 系统会自动释放
void sharedptr() {
//创建一个shared_ptr
shared_ptr<int> ptr1(new int(5));
//复制shared_ptr 增加引用计数
shared_ptr<int> ptr2 = ptr1;
cout << *ptr1 <<" "<<ptr1.use_count() << endl;
cout << *ptr1 <<" "<<ptr2.use_count() << endl;
//当最后一个shared_ptr被销毁时 内存会被自动释放
}
weak_ptr:
与 shared_ptr 结合使用 不增加引用计数 用于打破循环引用的问题
void weakptr() {
shared_ptr<int> sharedPTR(new int(2));
weak_ptr<int> weakPTR = sharedPTR;//不增加引用计数
cout << sharedPTR.use_count() << endl;
if (auto lockedPTR = weakPTR.lock()) {//尝试提升为shared_ptr
cout << *lockedPTR << endl;
}
else {
cout << "pointer has expired" << endl;
}
}
6.内存对齐
内存对齐是指将数据存储在特定的地址边界上,以提高访问效率。编译器通常会自动处理内存对齐,但了解其工作原理有助于优化性能
7.内存池
内存池是一种预先分配固定大小内存块的技术,用于减少频繁的内存分配和释放所带来的开销。适用于高性能要求的应用