如何为多个堆重载新操作符?

时间:2016-07-26 18:45:47

标签: c++ operator-overloading

在具有两个独立RAM存储区的嵌入式系统中,我有两个不同的堆(一个是来自FreeRTOS的低端内存区域的自定义实现,另一个是GCC在高端内存区域生成的堆)我希望能够选择新的用途。

2 个答案:

答案 0 :(得分:13)

你可以提供一个operator new重载,它接受第二个参数,告诉它从哪个内存区分配内存。您可以通过将它们放在new-expression中的类型之前的括号中来为operator new提供参数。这通常用于将new一个对象用于已经分配的存储(因为这是标准库提供的重载),但是任何东西都可以在那里传递,它将被传递给operator new

enum MemoryArea {
    LOWER,
    UPPER
};

void* operator new(std::size_t sz, MemoryArea seg) {
    if (seg == LOWER) {
        return allocateMemoryInLowerMemoryArea(sz);
    } else {
        return allocateMemoryInUpperMemoryArea(sz);
    }
}

void operator delete(void* p) {
    if (pointerIsInLowerMemoryArea(p)) {
        freeMemoryFromLowerMemoryArea(p);
    } else {
        freeMemoryFromUpperMemoryArea(p);
    }
}

int main() {
    Foo* p = new (LOWER) Foo;
    Foo* b = new (UPPER) Foo;
    delete p;
    delete b;
}

答案 1 :(得分:-4)

编辑:看到接受的答案,这是不正确的 - UseUpperMemoryNew会影响MyClass的分配,而不会影响MyClass中函数的分配。留下这个用于学习/后代/评论。

对于较低的内存区域,在全局命名空间中

#include <new>
#undef new

void* operator new (std::size_t size) throw (std::bad_alloc) { ... }
void* operator new (std::size_t size, const std::nothrow_t& nothrow_constant) { ... }
void* operator new[] (std::size_t size) throw (std::bad_alloc) { ... }
void* operator new[] (std::size_t size, const std::nothrow_t& nothrow_constant) throw() { ... }
void operator delete (void* ptr) throw () { ... }
void operator delete (void* ptr, const std::nothrow_t& nothrow_constant) throw() { ... }
void operator delete[] (void* ptr) throw () { ... }
void operator delete[] (void* ptr, const std::nothrow_t& nothrow_constant) throw() { ... }

对于高端内存区域,

void* new2 (std::size_t size) throw (std::bad_alloc) { ... }
void* new2 (std::size_t size, const std::nothrow_t& nothrow_constant) { ... }
void delete2 (void* ptr) throw () { ... }
void delete2 (void* ptr, const std::nothrow_t& nothrow_constant) throw() { ... }

#define UseUpperMemoryNew \
void* operator new (std::size_t size) throw (std::bad_alloc) { return new2(size); }\
void* operator new (std::size_t size, const std::nothrow_t& nothrow_constant) { return new2(size, nothrow_constant); }\
void* operator new[] (std::size_t size) throw (std::bad_alloc) { return new2(size); }\
void* operator new[] (std::size_t size, const std::nothrow_t& nothrow_constant) throw() { return new2(size, nothrow_constant); }\
void operator delete (void* ptr) throw () { delete2(ptr); }\
void operator delete (void* ptr, const std::nothrow_t& nothrow_constant) throw() { delete2(ptr, nothrow_constant); }\
void operator delete[] (void* ptr) throw () { delete2(ptr); }\
void operator delete[] (void* ptr, const std::nothrow_t& nothrow_constant) throw() { delete2(ptr, nothrow_constant); }

然后,低级内存是默认值,高级内存可以在类级别选择:

class MyClass
{
public:
    UseUpperMemoryArea
    void someFunction(); // new operator use in this function uses upper memory area
};

我发现你可能不会在全局命名空间之外重新定义新的 - 类级别重载是这里唯一的选择。