operator new []和非POD类型

nim*_*odm 5 c++ new-operator

我正在尝试重载operator new以跟踪内存分配(用于调试).我在分配非POD类型的数组时遇到了麻烦(例如,持有std :: string的类的数组).

似乎operator new调用为数组分配内存+ 8个字节,用于存储数组长度(可能是因为编译器可以在销毁数组时调用正确数量的析构函数).

如何operator new[]确定实际数据是放在返回的地址(POD数组)还是返回地址+8?(我需要这个,以便我可以搜索结构的指针)

Zan*_*ynx 1

我认为它会以与 new[] 知道要调用什么构造函数相同的方式进行:编译器告诉它。编译器会跟踪数据类型并知道它何时是 POD 类型。

但你真正的问题不是运算符 new[] 如何知道或编译器如何知道,而是你如何找到答案。

如果您分配的对象大小不是 8,则 new[] 请求的任何不能被 sizeof(object) 整除的大小都将包括对象的计数。这可能对你有用。

下面的代码似乎可以工作。我确信有很多方法可以打破它。

#include <new>
#include <iostream>

using namespace std;

class A {
    int x;
    int y;
};

class B {
    int x;
    int y;
    static int count;
public:
    B() : x(0), y(0) { ++count; }
    ~B() { --count; }
};

int B::count = 0;

template<class T>
T gcd(T a, T b)
{
    T tmp;
    while(b) {
        tmp = a % b;
        a = b;
        b = tmp;
    }
    return a;
}

void* operator new[](size_t count)
{
    size_t r = gcd(count, sizeof(size_t)*2);
    bool is_counted = r == sizeof(size_t);
    cout << count << " bytes requested and gcd is " << r << ' ' << (is_counted ? "is" : "is not") << " counted\n";
    return ::operator new[](count, std::nothrow);
}

int main()
{
    A* pa = new A[16];
    B* pb = new B[16];
    return 0;
}
Run Code Online (Sandbox Code Playgroud)