如何为多个堆重载新运算符

How can I overload the new operator for multiple heaps?

本文关键字:重载 运算符      更新时间:2023-10-16

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

您可以提供一个operator new重载,它接受第二个参数,告诉它从哪个内存区域分配内存。您可以将参数放在新表达式中类型之前的括号中,从而为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;
}

编辑:请参阅已接受的答案,这是不正确的-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
};

我发现您可能不会在全局命名空间之外重新定义new——类级重载是这里唯一的选项。