arduino上的C ++向量占用了大量的RAM足迹

时间:2012-12-06 17:25:33

标签: c++ memory-management vector arduino ram

无法在任何地方找到解决方案。希望在这个问题上变得更加开明。

我想为arduino项目使用动态数组。我遇到了一个在arduino平台here上使用向量的库。我使用了一个函数来监视arduino上的空闲RAM,我发现here

以下是我的代码示例:

Serial.print("Starting RAM: ");
Serial.println(freeRam());
Serial.println();

vector<int> intVector;

Serial.print("Remaining RAM after intVector declaration: ");
Serial.println(freeRam());
Serial.println();

vector<char> charVector;

Serial.print("Remaining RAM after charVector declaration: ");
Serial.println(freeRam());
Serial.println();


Serial.print("sizeof(intVector) = ");
Serial.println(sizeof(intVector));
Serial.print("sizeof(charVector) = ");
Serial.println(sizeof(charVector));

这是输出:

Starting RAM: 1684

Remaining RAM after intVector declaration: 1618

Remaining RAM after charVector declaration: 1584

sizeof(intVector) = 7
sizeof(charVector) = 7

似乎intVector分配占用了RAM的66个字节块。为此,看起来向量分配32 * 2 + 2 = 66字节的内存。同样,charVector分配占用了34个字节(32 * 1 + 2)。对于其他数据类型(例如char,float等),似乎存在这种分配32 * sizeof(type) +更改的模式。请注意arduino上的sizeof(int) = 2

我的问题是我想要填充这些向量的对象大到10-20个字节。由于ATMega328上只有2 kB RAM,我将无法按照目前的设计运行我的程序。对于具有segment的对象sizeof(segment) = 16,向量会占用一块522字节的RAM块。

所以我的问题是:

  1. 为什么当向量的大小只有7个字节时,向量会分配32 * sizeof(类型)字节的RAM,尽管它的类型是什么?

  2. 有没有更好的方法在arduino平台上使用某种动态数组?

  3. 是否有可以让我使用矢量的内存管理技术?

  4. 谢谢,如果这个问题重复,请提前抱歉!

    编辑:

    似乎载体初始化为容量为32.

    intVector.capacity() = 32;
    

    尝试使用

    intVector.reserve(1); // or
    intVector.resize(1);
    

    不会改变矢量的容量。

3 个答案:

答案 0 :(得分:5)

为了提高效率,向量一次分配的空间更多 - 您不希望每次尝试插入单个项目时重新分配。即使它仍然是空的,它很可能初始化为32个项目。

尝试打印vec.capacity()以找出它预留空间的元素数量。

向量是标准容器中空间效率最高的,它应该只使用每个元素所需的量加上一些不变的开销。

答案 1 :(得分:2)

快速浏览vector实现表明它总是保留额外的__UCLIBCXX_STL_BUFFER_SIZE__字节内存。该预处理程序符号在32中定义为system_configuration.h

因此,构造vector的默认值总是占用32个字节加上vector本身必须跟踪分配的内存,大小,容量等的任何开销。

您可以尝试将system_configuration.h中的预处理器定义更改为

#define __UCLIBCXX_STL_BUFFER_SIZE__ 0

但如果有任何东西依赖于总是被分配的空间,这可能会破坏代码。

答案 2 :(得分:0)

正如在另一个答案中所提到的,std :: vector总是提前分配一些内存,以防止每次插入时重新分配。要求系统获得更多内存是一个昂贵的过程,您希望尽可能避免这种过程。

编写自定义分配器。分配器是std :: vector的可选模板参数,使用它可以重新定义它如何获取内存(例如,使其预分配较小的数量,重新分配每个插入等)。有关这方面的更多信息,您可以在STL上查看Nicolai Josuttis的website。有一个免费的章节涵盖了分配器(标题“补充章节(PDF)”在侧栏中,还有sample code