C++的内存管理
C++的内存管理
C++的内存堆空间的申请和释放完全靠自己管理 程序运行时所需的内存空间分为固定部分和可变部分 固定部分:一般为代码区:存放二进制代码 数据区:存放全局变量和静态变量,常量
可变部分:堆区:运行方法的形参,局部变量,返回值,以及递归栈所需的空间,系统自动分配和回收 栈区:动态开辟的空间,存放“new”出来的对象在堆区中的真实数据,需要手动回收
栈区stack:由编译器自动分配释放,存放函数的参数值、局部变量的值灯,其操作方式类似于数据结构中的栈 堆区heap:由程序员手动分配释放,存放程序运行时创建的对象,其操作方式类似于数据结构中的堆 如果程序员不释放,程序结束时会自动释放,可能导致内存泄漏 未初始化数据区:存放未初始化的全局变量和静态变量 初始化数据区:存放已初始化的全局变量和静态变量
C 风格内存管理
malloc 函数(memory allocation)
用于在堆上分配指定字节数的内存。其原型如下:
#include <cstdlib>
void* malloc(size_t size);
参数:size - 要分配的内存字节数。 返回值:指向分配内存的指针,如果分配失败则返回 nullptr
free 函数(memory deallocation)
用于释放由 malloc 分配的内存。其原型如下:
#include <cstdlib>
void free(void* ptr);
参数:ptr - 指向要释放的内存的指针。 无返回值
桑婆
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
int* p = (int*)malloc(sizeof(int));
if(p == nullptr){
cout << "Memory allocation failed" << endl;
return 1;
}
*p = 666;
cout << "The value of *p is " << *p << endl;
free(p);
return 0;
}
Warning 类型转换:malloc 返回 void*,需要显式转换为所需类型的指针。 初始化:malloc 分配的内存未初始化,内容不确定。 释放对应性:由 malloc 分配的内存必须使用 free 释放,避免使用 delete。
C++ 风格内存管理
new 运算符(object creation)
用于在堆上分配对象,并调用其构造函数。
Type* ptr = new Type(parameters);
可以new对象 桑婆
#include <iostream>
using namespace std;
class Sample{
public:
int value;
Sample(int x):value(x){}
};
int main()
{
Sample* ptr = new Sample(10);
cout << ptr->value << endl;
return 0;
}
可以new数组:
#include <iostream>
using namespace std;
int main()
{
int* ptr = new int[10];
for(int i=0;i<10;i++){
ptr[i] = i;
}
for(int i=0;i<10;i++){
cout << ptr[i] << " ";
}
return 0;
}
delete 运算符(object destruction)
用于销毁对象,并释放其内存。 删除单个对象
delete ptr;
释放数组
delete[] ptr;
区别于 malloc 和 free
类型安全:new 返回正确类型的指针,免去了强制类型转换。 构造/析构:new 和 delete 自动调用构造函数和析构函数。 异常处理:在分配失败时,new 默认抛出 std::bad_alloc 异常,而 malloc 返回 nullptr。
可以用nothrow来避免new的异常:
In C++, std::nothrow is a constant of type std::nothrow_t, which is an empty class type used to differentiate between throwing and non-throwing allocation functions. When using std::nothrow, the new operator does not throw an exception if memory allocation fails. Instead, it returns a null pointer, allowing the programmer to handle the failure explicitly.

高级内存管理
使用 realloc 进行内存重分配
#include <cstdlib>
void* realloc(void* ptr, size_t size);
ptr:指向之前分配的内存块。 new_size:新的内存大小(以字节为单位)。 返回值:指向重新分配后的内存块的新指针。如果重新分配失败,返回 nullptr,原内存块保持不变。
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
int* ptr = (int*) malloc (5 * sizeof(int));
for(int i = 0; i < 5; i++)
{
ptr[i] = i;
}
cout << "Before realloc: ";
for(int i = 0; i < 5; i++){
cout << ptr[i] << " ";
}
int* ptr2 = (int*) realloc(ptr, 10 * sizeof(int));
for(int i=5;i < 10;i++)
{
ptr2[i] = i;
}
cout << "After realloc: ";
for(int i = 0; i < 10; i++){
cout << ptr2[i] << " ";
}
return 0;
}
output
Before realloc: 0 1 2 3 4 After realloc: 0 1 2 3 4 5 6 7 8 9
实现一个动态数组(使用realloc)
#include <iostream>
#include <cstdlib>
using namespace std;
class DynamicalArray {
public:
int* ptr;
int size;
DynamicalArray(int initial_size=1):size(initial_size), ptr((int*)malloc(size*sizeof(int))){cout<<"Create"<<endl;}
~DynamicalArray(){free(ptr);cout<<"Delete"<<endl;}
void resize(int new_size) {
int* new_ptr = (int*)realloc(ptr, new_size*sizeof(int));
if(new_ptr) {
ptr = new_ptr;
size = new_size;
cout<<"Resize to "<<size<<endl;
}
}
int getSize() const {return size;}
void show(){
for(int i=0;i<size;i++){
cout<<ptr[i]<<" ";
}
cout<<endl;
}
};
int main()
{
DynamicalArray arr(5);
for(int i=0;i<5;i++){
arr.ptr[i] = i;
}
arr.show();
arr.resize(10);
for(int i=5;i<10;i++){
arr.ptr[i] = i;
}
arr.show();
return 0;
}
Enjoy Reading This Article?
Here are some more articles you might like to read next:
- Google Gemini updates: Flash 1.5, Gemma 2 and Project Astra
- Displaying External Posts on Your al-folio Blog
- Graph RAG with Milvus —— 纯向量库造图的多跳推理
- Hierarchical Indices 层级索引 —— 先粗后细的两级检索
- HyDE 与 HyPE —— 假设检索技术的两个方向
- 二叉树刷题总结
- RAG 技术体系化分类——从 Pipeline 阶段到失败模式
- MemoRAG 记忆增强型 RAG 总结
- Microsoft GraphRAG 基于知识图谱的 RAG 总结
- Multimodal RAG with Captioning 图像描述型多模态 RAG 总结