【发布时间】:2016-07-26 18:45:46
【问题描述】:
在具有两个独立 RAM 内存区域的嵌入式系统中,我有两个不同的堆(一个是来自 FreeRTOS 的自定义实现,位于较低的内存区域,另一个是 GCC 在较高的内存区域生成的堆),我想以便能够选择新使用的堆。
【问题讨论】:
在具有两个独立 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;
}
【讨论】:
operator new 重载实际上对参数做了什么。见§[expr.new]/13。
编辑:请参阅已接受的答案,这是不正确的 - UseUpperMemoryNew 会影响 MyClass 的分配,而不是 MyClass 中函数内的分配。 将其留给学习/后代/ cmets。
对于较低的内存区域,在全局命名空间中
#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); }
那么,lower memory 是默认的,upper memory 可以在类级别选择:
class MyClass
{
public:
UseUpperMemoryArea
void someFunction(); // new operator use in this function uses upper memory area
};
我发现你不能在全局命名空间之外重新定义 new - 类级重载是这里唯一的选择。
【讨论】:
throw(...) 异常规范是 deprecated。
operator new 重载的工作方式。您的UseUpperMemoryNew 重载不会用于MyClass,它们将用于分配新的MyClass 对象。