operator new[]和非POD类型

5
我试图重载operator new以跟踪内存分配(用于调试)。当分配非POD类型的数组时(例如,一个持有std :: string的类的数组),我遇到了麻烦。
似乎operator new被调用来为数组分配内存+8个字节,这些字节用于存储数组长度(可能是为了在销毁数组时编译器可以调用正确数量的析构函数)。 operator new[]如何知道实际数据是放置在返回地址(PODs数组)还是在返回地址+8处?(我需要这样做以便可以搜索指针结构)
1个回答

1
我想,operator new[]也是通过编译器告诉它该调用哪些构造函数来完成的。编译器会跟踪数据类型,并知道它是POD类型还是其他类型。
但你真正的问题不是operator new[]或编译器如何知道这个信息,而是你如何发现它。
如果你要分配的对象大小不是8,则任何由new[]请求的大小,如果不能被对象的sizeof整除,都会包括对象计数。这可能适合你。
下面的代码似乎有点可行,但我相信还有很多方法可以破坏它。
#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;
}

我如何知道分配对象的大小?operator newoperator new[]都接收以字节为单位的总大小,而不是单个结构的大小。我猜这是一个没有好解决方案的问题... - nimrodm
@nimrodm:我想我是在考虑每个类的operator new。 - Zan Lynx
@nimrodm:我刚刚添加的示例代码似乎适用于大于一个size_t的类。可能会对你有所帮助。 - Zan Lynx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接