operator new []和非POD类型

时间:2014-01-29 19:54:36

标签: c++ new-operator

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

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

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

1 个答案:

答案 0 :(得分: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;
}