struct、class和STL的统一内存管理
2012-12-22 09:44
429 查看
转自:http://blog.csdn.net/lifesider/article/details/6443375
利用C++的new和delete操作符重载特性,可以对自定义的struct和class进行统一内存管理,再加上STL allocator的开放特性,便可以将STL容器对象的内存管理并入struct和class的内存管理,进而将这三者的内存管理统一。
首先实现自定义的内存管理算法框架,开放接口为allocate和deallocate,实现库为memmgr.dll
class memory_manager
{
public:
virtual void* allocate(size_t size) = 0;
virtual void deallocate(void* ptr, size_t size) = 0;
}
通过显示加载或隐式链接得到memmgr.dll导出的自定义内存管理框架接口指针
memory_manager* ptrmemmgr;
针对struct和class,建立公共基类,并调用导出的内存管理相关接口
class basic_object
{
public:
void* operator new(size_t size)
{
return (ptrmemmgr->allocate(size);
}
void operator delete(void* ptr, size_t size);
{
ptrmemmgr->deallocate(ptr, size);
}
};
自此,对于任意的自定义struct和class,都可以公共继承自basic_object,调用new和delete时便会调用basic_object::new和basic_object::delete接口,如下示例
class example : public basic_object
{
public:
// 这里省略成员函数和成员变量的声明和实现,就像没有继承自basic_object时一样
};
当对example进行new和delete操作时,编译器将产生调用basic_object::new和basic_object::delete的代码
至此,已将struct和class的内存管理统一了
对于STL,由于STL的所有容器都有一个allocator的模板参数,因此我们需要自定义allocator
template<typename T>
class newallocator : public std::allocator<T>
{
public:
template<typename O>
struct rebind
{
typedef newallocator<O> other;
}
template<typename O>
newallocator(newallocator<O> const&) throw()
{
}
template<typename O>
newallocator<T>& operator=(newallocator<O> const&) throw()
{
return (*this);
}
T* allocate(size_type count)
{
return (basic_object::operator new(count * sizeof(T));
}
void deallocate(T* ptr, size_type count)
{
basic_object::operator delete(ptr, count * sizeof(T));
}
};
然后,对于任何容器,只需使用上面自定义的newallocator即可,如
std::vector<int, newallocator<int>> vtexample;
std::map<int, int, std::less<int>, newallocator<std::pair<int const, int>>> mapexample;
至此,STL容器的内存管理也并入memory_manager里了,三者的内存管理达成统一。
注意:
(1)由于这里只重载了operator new和operator delete,因此只为struct和class的单个对象有效,对于数组仍会使用全局的::operator new[]和::operator dlete[]。当然也可以重载operator new[]和operator delete[]操作符,这样便将数组的内存管理也并入memory_manager里了。
(2)使用自定义的内存管理框架后,对于struct,由于有了成员函数,便不能使用声明时初始化数组的方式,如
struct stu stuexample = {0}; // 这种使用方式将导致编译错误,但可以使用memset(&stuexample, 0, sizeof(stu))
(3)可以为operator new(或者new[])加入更多的参数,如文件名和行数,进行debug下的内存泄漏检测
(4)重载operator delete[]时,应该使用operator delete[](void* ptr),否则使用operator delete[](void* ptr, size_t size)时传入的参数size只是一个对象的大小,而不是整个数组的大小
(5)如果自定义实现的内存管理框架中可以保证不产生异常,对于basic_object和newallocator可以使用throw()进行优化
利用C++的new和delete操作符重载特性,可以对自定义的struct和class进行统一内存管理,再加上STL allocator的开放特性,便可以将STL容器对象的内存管理并入struct和class的内存管理,进而将这三者的内存管理统一。
首先实现自定义的内存管理算法框架,开放接口为allocate和deallocate,实现库为memmgr.dll
class memory_manager
{
public:
virtual void* allocate(size_t size) = 0;
virtual void deallocate(void* ptr, size_t size) = 0;
}
通过显示加载或隐式链接得到memmgr.dll导出的自定义内存管理框架接口指针
memory_manager* ptrmemmgr;
针对struct和class,建立公共基类,并调用导出的内存管理相关接口
class basic_object
{
public:
void* operator new(size_t size)
{
return (ptrmemmgr->allocate(size);
}
void operator delete(void* ptr, size_t size);
{
ptrmemmgr->deallocate(ptr, size);
}
};
自此,对于任意的自定义struct和class,都可以公共继承自basic_object,调用new和delete时便会调用basic_object::new和basic_object::delete接口,如下示例
class example : public basic_object
{
public:
// 这里省略成员函数和成员变量的声明和实现,就像没有继承自basic_object时一样
};
当对example进行new和delete操作时,编译器将产生调用basic_object::new和basic_object::delete的代码
至此,已将struct和class的内存管理统一了
对于STL,由于STL的所有容器都有一个allocator的模板参数,因此我们需要自定义allocator
template<typename T>
class newallocator : public std::allocator<T>
{
public:
template<typename O>
struct rebind
{
typedef newallocator<O> other;
}
template<typename O>
newallocator(newallocator<O> const&) throw()
{
}
template<typename O>
newallocator<T>& operator=(newallocator<O> const&) throw()
{
return (*this);
}
T* allocate(size_type count)
{
return (basic_object::operator new(count * sizeof(T));
}
void deallocate(T* ptr, size_type count)
{
basic_object::operator delete(ptr, count * sizeof(T));
}
};
然后,对于任何容器,只需使用上面自定义的newallocator即可,如
std::vector<int, newallocator<int>> vtexample;
std::map<int, int, std::less<int>, newallocator<std::pair<int const, int>>> mapexample;
至此,STL容器的内存管理也并入memory_manager里了,三者的内存管理达成统一。
注意:
(1)由于这里只重载了operator new和operator delete,因此只为struct和class的单个对象有效,对于数组仍会使用全局的::operator new[]和::operator dlete[]。当然也可以重载operator new[]和operator delete[]操作符,这样便将数组的内存管理也并入memory_manager里了。
(2)使用自定义的内存管理框架后,对于struct,由于有了成员函数,便不能使用声明时初始化数组的方式,如
struct stu stuexample = {0}; // 这种使用方式将导致编译错误,但可以使用memset(&stuexample, 0, sizeof(stu))
(3)可以为operator new(或者new[])加入更多的参数,如文件名和行数,进行debug下的内存泄漏检测
(4)重载operator delete[]时,应该使用operator delete[](void* ptr),否则使用operator delete[](void* ptr, size_t size)时传入的参数size只是一个对象的大小,而不是整个数组的大小
(5)如果自定义实现的内存管理框架中可以保证不产生异常,对于basic_object和newallocator可以使用throw()进行优化
相关文章推荐
- struct、class和STL的统一内存管理
- STL SGI内存的管理
- 【转载】class和struct的区别 类的内存结构
- class和struct的区别以及类的内存结构
- struct/class/union内存对齐原则
- spark1.6统一内存管理(UnifiedMemoryManager)
- 理解stl内存管理方式和cocos2dx不符
- [c/c++]class/struct数据在内存中的布局
- STL之内存管理
- C#开发日志[2013-12-6]内存暴增/class与struct的异同
- struct/class/union内存对齐原则
- 谈STL二级内存管理
- 内存储器管理概述、内存分配与释放、地址映射机制(mm_struct, vm_area_struct)、malloc/free 的实现
- class和struct的区别 类的内存结构
- SGI STL 内存管理
- STL之内存管理
- C/C++中 union/struct/class的内存对齐
- Java自动内存管理机制(一) JVM、Class
- Spark性能调优(十)之Spark统一内存管理
- struct/class等内存字节对齐问题详解