简体   繁体   English

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

[英]How can I overload the new operator for multiple heaps?

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

You could provide an operator new overload that accepts a second argument telling it which memory area to allocate memory from. 您可以提供一个operator new重载,它接受第二个参数,告诉它从哪个内存区分配内存。 You can give arguments to operator new by putting them in parenthesis before the type in your new-expression. 您可以通过在new-expression中的类型之前将它们放在括号中来为operator new提供参数。 This is usually used to new an object into already-allocated storage (since that's the overload provided by the standard library), but anything can be passed there and it will be passed on to 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;
}

Edit: See accepted answer, this is incorrect - UseUpperMemoryNew would affect allocations of MyClass, not allocations within functions in MyClass. 编辑:请参阅接受的答案,这是不正确的 - UseUpperMemoryNew会影响MyClass的分配,而不会影响MyClass中函数的分配。 Leaving this around for learning / posterity / comments. 留下这个用于学习/后代/评论。

For the lower memory area, in global namespace 对于较低的内存区域,在全局命名空间中

#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() { ... }

For the upper memory area, 对于高端内存区域,

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); }

Then, lower memory is default, upper memory may be chosen at the class level: 然后,默认值较低的内存,可以在类级别选择较高的内存:

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

I discovered that you may not redefine new outside of the global namespace - class-level overloading is the only option here. 我发现你可能不会在全局命名空间之外重新定义新的 - 类级别重载是这里唯一的选择。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM