【问题标题】:Keeping track of used memory with overloaded new and delete operator?使用重载的 new 和 delete 运算符跟踪使用的内存?
【发布时间】:2018-04-12 07:48:55
【问题描述】:

好的,我的目标是跟踪已分配的内存。为此,我创建了一个静态变量并重载了 new 和 delete 运算符。不过我有点困惑。当我创建新的 int 对象时,它分配了 4 个字节的内存,但是当我删除指向这个 int 的指针时,它说 8 个字节已被删除。有没有办法准确跟踪它?再往前走,我还想跟踪动态创建的对象并跟踪它使用了多少内存。 这是我的代码:

#include<iostream>
#include<stdlib.h>

static int memory{0};

void* operator new(std::size_t sz){
    memory+= sz;
    return std::malloc(sz);
}

void operator delete(void* ptr) noexcept{
    memory-= sizeof(ptr);
    std::free(ptr);
}

int main()
{
    int * p = new int;
    *p = 2;
    std::cout << memory; // memory = 4

    delete p;
    std::cout << memory; // memory = -4 
}

【问题讨论】:

  • 这可能是一个竞争条件。对内存的原子变量尝试相同的操作。
  • sizeof(ptr) 不是您分配的数量,而是指针的大小(x64 上为 8 个字节)
  • @davidhigh:只有一个线程。
  • 您可以分配更多以节省返回指针附近的大小。小心对齐。

标签: c++


【解决方案1】:

有点烦人,不是吗? free 知道要释放多少内存,但不会告诉你。

实际的解决方案是在malloc 请求中添加一个额外的sizeof(size_t),并使用返回分配的第一个字节来存储sz。在operator delete 中,您执行相反的操作:查找ptr 之前的sizeof(size_t) 字节。

所以你得到的代码是memory-=static_cast&lt;size_t*&gt;(prt)[-1];[-1] 看起来很吓人,我知道。少数几个有意义的案例之一。

【讨论】:

    【解决方案2】:

    你在这里有一个错误的假设。 sizeof 指针返回指针的大小,而不是它指向的结构的大小。因此,无论您分配什么类型的结构(无论是int、类的实例还是数组),您总是减去相同数量的内存。

    您应该检查指针指向的结构的大小,但在这段代码中很难。由于您将 void* 作为参数传递,因此您无法取消引用它,您必须知道该指针是什么类型。
    我想您可以尝试使用模板函数来保留指针类型(并能够取消引用它)。

    【讨论】:

    • 没错,我怎么会错过呢?我想我必须重新考虑删除运算符重载。
    • 实际上,您非常清楚指针的类型。这是您从operator new 返回的任何内容。您错过了 operator new/operator delete 对的重点;他们齐头并进。
    • @MSalters 嗯...我想我可以将 new 运算符中的行更改为 memory+= sizeof(std::malloc(sz)) 而不是 memory+= sz
    • @DerekJohnson:当然可以,但sizeof(malloc) 可能是 4 或 8(32 或 64 位系统),所以实际上你会计算 数字 分配。这要容易得多。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-04
    • 2012-11-10
    • 2014-03-26
    • 2013-03-12
    • 2021-03-13
    • 2012-05-18
    相关资源
    最近更新 更多