在一个具有两个单独的RAM存储区域的嵌入式系统中,我拥有两个不同的堆(一个是FreeRTOS在较低存储区域中的自定义实现,另一个是由GCC在较高存储区域中生成的堆),我希望能够选择new使用哪个堆。
您可以提供一个重载了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
};
operator new
重载的工作方式。你的 UseUpperMemoryNew
重载不会在 MyClass
中使用,它们将用于分配新的 MyClass
对象。 - Miles Budnek
operator new
重载实际上如何处理参数。请参见§[expr.new]/13。 - Miles Budnek