c++内存管理

在c++中,内存管理是一个重要的主题,涉及到如何分配和释放内存。以下是一些关键概念和方法。

1.内存管理

C++ 程序的内存通常分为以下几个部分:

  • 栈(Stack):用于存储局部变量,函数调用时自动分配和释放。
    • 用途:用于存储局部变量和函数调用相关的数据(如函数参数,返回地址等)。
    • 特点
      • 先入后出,后入先出
      • 自动分配和释放内存
      • 内存分配效率高,但容量有限。
    • 示例
    void func(){
    	int x = 10; //x存储栈中
    }
    
  • 堆(Heap):用于动态分配内存,需手动管理。
    • 用途:用于自动分配内存,程序运行时手动申请和释放。
    • 特点
      • 需要使用newmalloc分配内存,使用deletefree释放内存。
      • 容量大,但管理复杂,容易导致内存泄漏。
    • 示例
    int* ptr = new int(10);//动态分配内存;
    delete ptr;   //手动释放内存
    
  • 全局/静态区:存储全局变量和静态变量。
    • 用途:存储全局变量和静态变量。
    • 特点
      • 程序运行期间一直存在,直到程序结束时释放。
      • 全局变量在整个程序中可见,静态变量在声明的作用域内可见。
    • 示例
    int globalVar = 10; //全局变量
    void func(){
     static int staticVar=20; //局部变量
    }
    
  • 代码区:存储程序的可执行程序。
    • 用途:存储程序的可执行代码。
    • 特点
      • 通常只读,防止代码被意外修改。
      • 包含函数的机器指令。
    • 示例
    void func(){
    	//函数的机器指存储在代码区
    }
    

2.动态内存分配

C++ 提供了newdelete 操作符用于动态分配和释放内存:

int* ptr = new int;//分配一个整数
*ptr = 10;//使用分配的内存
detele ptr;//释放内存

对于数组:

int* arr = new int[5]; //分配一个整数数据
delete[] arr; //释放数组内存

3.常见问题

  • 内存泄漏:动态分配的内存未释放。
  • 悬空指针:释放内存后继续使用指针。
  • 双重释放:对同一块内存调用多次detete

4.智能指针

C++11引入智能指针(如std::unique_ptrstd::shared_ptr),可以自动管理内存,减少手动释放风险:

#include <memory>

std::unique_ptr<int> ptr = std::unique_ptr(10);

4.1 std::unique_ptr

std::unique_ptr是一种独占所有权的智能指针,确保同一时间只有一个智能可以拥有该内存。它在超出作用域时自动释放内存。

void example(){
	std::unique_ptr<int> uptr =std::make_unique<int>(5);//使用uptr
}//uptr 超出作用域,内存自动释放

4.2 std::shared_ptr

std::shared_ptr允许多个指针共享同一块内存。它使用引用计数来管理内存,当最后一个指针超出作用域时,内存才会被释放。

void exampe(){
	std::shared_ptr<int> sptr1 =std::make_shared<int>(10);
	std::stared_ptr<int> sptr2 = sptr1;//sptr1和sptr2共享同一块内存
}//当 sptr1 和 sptr2 超出作用域,内存自动释放

4.2.1 std::make_shared的使用

std::make_shared是个工厂函数,用于创建std::shared_ptr对象。它比直接使用std::shared_ptr构造函数更高级,因为他只分配一次内存,同时存储对象和控制块。

#include <memory>
#include <iostream>
class MyClass{
public:
	MyClass(int value) : value_(value){
		std::cout << "MyClass constructed with value:" << value << std::endl;
	}
	~MyClass(){
		std::cout << "MyClass destroyed with value:" << value_ << std::endl;
		}
		int getValue() const {return value_;}
private:
	int value_;
};

int main(){
	//使用std::make_shared 创建 shared_ptr
	auto ptr = std::make_shared<MyClass>(42);
	std::cout << "Value:"<< ptr->getValue() << std::endl;
	return 0;
}

使用std::make_shared的优点:
1.更高效:只分配一次内存,同时存储对象和控制块
2.更安全:避免了内存泄漏的风险
3.更简洁:代码更易读和维护

4.3 std::weak_ptr

std::weak_ptr是与std::shared_ptr配合使用的智能指针,用于解决循环引用的问题。它补增加引用计数。

void example(){
	std::shared_ptr<int> sptr = std::make_shared<int>(20);
	std::weak_ptr<int> wptr = sptr;//wptr 不增加引用计数
}

通过合理使用智能指针,可以有效避免内存管理中的常见问题。

5.内存对齐

内存对齐是为了提高访问效率,编译器可能会在分配内存时插入填充字节。

6.调试工具

使用工具(如 Valgrind)可以检查内存泄漏和其他内存问题。

通过合理使用动态内存和智能指针,可以有效避免内存管理中的常见问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值