我想跟踪所有 STL 容器(如映射、列表、向量等)分配的所有内存(由 std lib 分配的大小)。我只想跟踪 STL 容器而不是常规对象创建。基本上想要覆盖 std lib 的 new 和删除。
Example
class demo {
public:
int i;
std::list<int> mylist;
}
int main() {
demo dd = new demo(); // -> Don't want to track this. Just want to track
// mylist(size of my list)
}
我发现 std 有它自己的分配器选项。例如列表有它是分配器
template < class T, class Alloc = allocator<T> > class list;
如果我没有定义任何内容,默认分配器是什么。我有数千个列表,但没有一个有分配器,我不想手动更改每个列表。所以,我在想是否有办法可以用我的分配器替换默认分配器。
这个怎么做 ?
标准容器的默认分配器是std::allocator http://en.cppreference.com/w/cpp/memory/allocator,它用于所有标准容器(std::vector
, std::list
等)当未提供分配器时。
要跟踪分配和释放,您必须创建一个可用于跟踪的分配器。你可以使用这样的东西:
template<typename _Ty>
struct MyAllocator
{
typedef _Ty value_type;
static _Ty* allocate(std::size_t n)
{
//Code that runs every allocation
...
return std::allocator<_Ty>{}.allocate(n);
}
static void deallocate(_Ty* mem, std::size_t n)
{
//Code that runs every deallocation
...
std::allocator<_Ty>{}.deallocate(mem, n);
}
};
MyAllocator
镜子std::allocator
但它允许您在发生分配时运行一些自己的代码。你想放什么取决于你。
有两种方法可以让所有容器都使用您的分配器。
-
您可以替换所有实例std::list
(or std::vector
, std::map
等)带有模板别名。为了std::list
别名看起来像这样:
template<typename _Ty>
using MyList = std::list<_Ty, MyAllocator<_Ty>;
替换所有实例std::list
with MyList
。现在您的分配器已被所有容器使用。将此应用到另一个容器更改list
容器的名称(例如vector
将别名重命名为MyVector
并改变std::list
to std::vector
).
-
如果您无法编辑该文件或不想修改它,还有另一个选择。您可以使用宏来替换所有实例list
与您定义的类。该类必须已在中声明namespace std
你必须确保包括<list>
在设置宏之前。设置为std::list
看起来像这样:
#include <list>
namespace std
{
template<typename _Ty, typename _Alloc = MyAllocator<_Ty>>
using tracked_list = list<_Ty, _Alloc>;
}
#define list tracked_list
对于不同的容器,更改list
到您想要更换的任何容器(例如vector
change tracked_list
to tracked_vector
在两个位置并替换list
with vector
在所有三个地点。确保此代码位于可以使用的任何其他包含之前std::list
。如果将其放入头文件中,请在其他内容之前包含该头文件。如果它在源文件中,请将其放在文件的顶部。此代码不会覆盖用户提供的分配器,但会使您的分配器成为默认分配器。
此方法将更改变量名称,这可能会影响您的代码。如果可能,您应该使用方法 1。但是,如果您有无法更改的代码或外部标头中的代码并且这也需要应用于该代码,则此方法应该可行。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)