是否可以使用运算符new从堆以外的其他位置进行分配
Is it possible to use operator new to allocate from elsewhere than the heap?
这是我的应用程序的上下文:我正在开发一个使用不同设备的RAM的嵌入式系统。一部分在微控制器的内部RAM(128kB)中,另一部分是外部RAM(1MB)。这些存储器被映射到微控制器的地址空间中,但在非连续区域中。
内部RAM用于系统堆栈、任务堆栈和堆。外部RAM用于静态分配的数据(池、缓冲区和所有"static ...
"内容)
我试图实现一个简单的内存管理结构,作为其中的一部分,我能够创建一个分配器,该分配器可以使用operator new
的分配算法,但使用另一个内存源,而不是系统堆,而是其他地方的内存区域。你知道这是否可能吗?
一个使用的例子可以是保留100kB的外部RAM,并创建一个分配器来管理它,然后将它交给需要这个内存的指定任务。
static const uint8_t* ramBase = reinterpret_cast<uint8_t*>(0x80000000);
static const uint32_t ramAreaSize = 0x19000; //100kB
BufferAllocator allocator(ramBase, ramAreaSize);
//...
//Assuming operator new is overloaded to use BufferAllocator
MyObject * obj = new (allocator) MyObject(some, parameter);
//...
问题是:我如何(如果可能的话)实现BufferAllocator
,以便使用operator new
来管理原始内存区域?
void* BufferAllocator::allocate(uint32_t bytes)
{
//I would like to write something like this
//and so let the responsibility to manage this memory area to "new"
//so I don't have to reimplement (or reuse) a different custom
// allocator
return ::operator new(ramBase, ramAreaSize, bytes)
}
我也面临着同样的问题,我能找到的唯一解决方案就是编写自己的malloc
和free
。我不需要任何特别的东西,所以我只是按照K&R的C编程语言(他们有一个简单的例子记录)。
然后我创建了两个堆:一个用于内部内存,另一个用于外部内存。我的堆栈在一个完全不同的内存块中(STM32F4上的CCRAM),所以我不需要担心sbrk
。然而,我必须根据数据和bss段的大小知道内部SRAM堆的起始地址。这是根据链接器脚本注入的extern
符号确定的。
我有足够的堆信息来了解它的当前大小、可用空间量以及是否有足够的连续内存来执行分配。如果内部SRAM内存不足,则尝试外部SRAM。如果内存不足,这与默认的malloc
内存不足没有什么不同。
我使用的是GNU工具链,所以我可以使用--wrap选项来覆盖C标准库的默认malloc
、free
、realloc
和calloc
(实际上是malloc_r
、free_r
、realloc_r
和calloc_r
,因为我使用的都是newlib)。由于new
和delete
最终打电话给malloc
和朋友,我能够让它工作(至少满足我的需求)。
我对这种方法不是很有信心,但这是我在能力范围内能做的最好的事情。仔细考虑。
我很想知道一个更简单的解决方案。
没有向operator new
或malloc()
提供内存区域的标准方法。在类似POSIX的系统中,malloc()
调用brk()
、sbrk()
,可能还有mmap()
来获取区域,因此您可以"捕获"这些调用并提供自己的实现,但这是不可移植的(这对mmap()
来说是个问题)。
根据您的工具链,您可能能够向malloc()
和/或operator new
"解释"它应该在一些链接器脚本或类似的东西中处理两个或多个不同的内存区域。但这并不能保证。
除此之外,我能想到的唯一通用解决方案是在项目中使用不同的通用内存管理器(如jemalloc
),并找到一种方法来为您的目的配置它。
- GL_SHADERSTORAGE_BUFFER位置是否与其他着色器位置冲突
- 我的 SonarQube C++扫描成功,但结果仅标记重复项,而没有标记其他标记的位置
- 我正在尝试为字符打印一些相应的值,但条件总是转到其他位置
- QT 无法识别 UTF-8 编码,适用于其他所有位置
- C 从特定位置插入其他向量中的载体
- 为什么在这种情况下星号位置有所不同,而其他位置则没有
- 无法从非原点的其他位置旋转对象
- 强迫G 在一个位置寻找升压,忽略其他设置
- 在构造函数以外的任何其他位置访问相机时,我的相机指针返回 null
- 我可以期望某些堆内存位置比C 中的其他位置更快
- 类定义中定义的成员函数的编译方式是否与C++中其他位置定义的成员函数不同
- 将图像文件(.BMP)复制到其他位置
- 将指针移动到其他位置后删除分配的内存
- 是否可以使用运算符new从堆以外的其他位置进行分配
- 如何使用指针将数组复制到内存中的其他位置
- 将证书文件复制到其他位置
- 如何将对象放置在堆以外的其他位置
- 正在使用标准流将文件复制到其他位置
- 如果其他位置
- 在类作用域内定义方法时,除非在原始 cpp 文件中的其他位置调用方法,否则项目不会编译