浅谈C++中各种不同意义的new和delete的使用
new和delete的基础用法
在C++中,我们可以使用new关键字来动态地为对象分配内存,使用delete关键字来释放该内存。通常的使用方式如下:
int* p = new int; // 为一个int类型的数据分配内存空间并返回指向该内存的指针
*p = 10; // 对该内存空间进行赋值
delete p; // 释放该内存空间
在这个例子中,我们使用new分配了一个整型变量的内存空间,并将该指针赋值给了指针变量p。
使用delete释放内存空间时,我们只需传入用new分配的指针即可。
new和delete的数组用法
除了基础用法外,new和delete关键字还可以用于数组的动态内存分配和释放。数组的动态内存分配如下:
int* arr = new int[10]; // 分配一个长度为10的整型数组
注意,在使用数组动态内存分配时,我们需要指定数组的长度。使用delete来释放数组的内存空间时,同样需要特别注意,它的使用方式如下:
int* arr = new int[10]; // 分配一个长度为10的整型数组
delete[] arr; // 释放该数组占用的空间
使用了delete[]关键字,而不是简单的delete关键字。
new和delete的placement new操作符
除了基本的new操作符外,C++还提供了placement new操作符。placement new操作符可以在已分配的内存地址上构造一个新的对象,而不是分配新的内存空间。其语法如下:
new (已分配的地址) 类型名(arguments);
这个操作符通常用于以下情况:
- 在特定的地址上构造新的对象,如对象池、内存池等。
- 重载了new操作符的类,自定义管理内存时可以用到。
下面是一个基于对象池的示例:
// ObjectPool类,实现了对象的分配和销毁
template <typename T>
class ObjectPool
{
public:
ObjectPool(int count = kInitialCount) // 初始化对象池,count为对象池中对象的个数
{
for (int i = 0; i < count; ++i)
{
m_objectList.push_back(new T);
}
}
~ObjectPool() // 销毁对象池,释放对象内存空间
{
for (auto ptr : m_objectList)
{
delete ptr;
}
}
// 获取一个对象
T* acquireObject()
{
if (m_objectList.empty())
{
m_objectList.push_back(new T);
}
T* ptr = m_objectList.front();
m_objectList.pop_front();
return ptr;
}
// 释放一个对象
void releaseObject(T* object)
{
m_objectList.push_back(object);
}
private:
static const int kInitialCount = 10;
std::list<T*> m_objectList; // 存储对象指针的链表,对象池中已分配的对象
};
// 示例
int main()
{
ObjectPool<int> pool(5); // 分配一个容量为5的整型对象池
int* p1 = pool.acquireObject(); // 获取一个整型对象
*p1 = 10; // 修改对象值
pool.releaseObject(p1); // 释放整型对象
int* p2 = pool.acquireObject();
std::cout << *p2 << std::endl; // 输出"10",对象值得到了保持
return 0;
}
在这个例子中,我们自定义了ObjectPool类,并实现了对象池的分配和释放。在acquireObject()方法内,我们使用placement new操作符在已分配的内存地址上构造新的对象。
new和delete的不同重载
new和delete支持重载,可以根据需要对内存管理行为进行修改。重载new和delete可以为开发者提供更好的内存管理方式。
定义自己的new和delete
我们可以定义自己的new和delete方法,来实现更特殊的内存管理方式。例如,我们可以重载new和delete,用于内存泄露检测、统计对象使用次数等。
void* operator new(size_t size)
{
void* ptr = malloc(size);
printf("Custom new called, size = %zu, ptr = %p\n", size, ptr); // 格式化输出分配内存大小和指针地址
return ptr;
}
void operator delete(void* ptr)
{
printf("Custom delete called, ptr = %p\n", ptr); // 格式化输出释放指针地址
free(ptr);
}
在这个例子中,我们根据需要定义了自己的new和delete方法,并使用printf输出内存分配/释放的相关信息。
定义自己的new[]和delete[]
我们也可以定义自己的new[]和delete[],用于自定义内存管理。
void* operator new[](size_t size)
{
void* ptr = malloc(size);
printf("Custom new[] called, size = %zu, ptr = %p\n", size, ptr); // 格式化输出分配内存大小和指针地址
return ptr;
}
void operator delete[](void* ptr)
{
printf("Custom delete[] called, ptr = %p\n", ptr); // 格式化输出释放指针地址
free(ptr);
}
在这个例子中,我们同样定义了自己的new[]和delete[]方法,并用printf输出内存分配/释放的相关信息。
总结
C++中的new和delete关键字提供了灵活的内存管理方式。除了基础的内存申请和释放方法外,我们还可以使用数组形式的new和delete、placement new、和重载new和delete方法。
这些灵活的内存管理方法可以为我们的程序提供更好的性能和可维护性。在实际应用中,我们应该根据实际需要,灵活地使用这些内存管理方法。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:浅谈C++中各种不同意义的new和delete的使用 - Python技术站