通过检查头文件(仅模板函数,源代码):
http: //playground.arduino.cc/uploads/Code/QueueArray.zip
我相信队列的构造函数会让你陷入这个麻烦。我在分配队列中的对象时遇到了麻烦。
我决定只将引用作为数字放在那里,然后在接收端将其设置为对象类型指针的地址值。这是顺便说一句。一个冒险的策略!
为什么不直接使用 c_str 属性https://www.arduino.cc/en/Reference/CStr?
编辑:这个评论的答案太长了:
Arduino 是一个 µProcessor,内存非常有限(~2K)。(您的程序为 32K,闪存中类似)。
请记住,它也是一台内存管理有限的机器。所以堆栈和堆都非常小,一般来说,当使用堆时,它很快就会变得非常碎片化。
作为一名查看您的代码的 C++ 程序员,您可能会认为字符串实际上是堆栈分配的。(提示:那里没有新keyword
的)所以即使它在内部将字符保存在堆中,这也应该允许您假设当您退出范围时字符串对象将被销毁。
(您还应该期望它会自行清理,并释放用于字符的动态内存。根据您的库版本,这确实有效,或者重新分配/释放存在问题,使得比我们需要在这里讨论的更糟糕的事情..)
了解堆和栈的区别:
C++ 对象实例化
您可以使用 arduino 字符串来最小化 ehap 碎片,例如在执行字符串操作之前保留内存。
但是每次您决定使用字符串时,您很可能会将堆碎片化,特别是如果您在退出范围后让它保持活动状态(用于队列的另一端)。
为了避免碎片问题,(记住它是一个小系统),您可以使用enums
或类似的预定义消息。但是,如果您坚持认为您实际上需要将字符串排入队列,我有一个更好的建议。
您可以创建一个小的全局字符串数组,以保存将要排队的字符串。(当然会限制队列大小,因为队列中的消息不能超过字符串对象数组所允许的数量。这个数组将被堆栈分配,但每个字符串引用的字符将被堆分配。这允许你让队列的读取器清除字符串,从而释放堆上的内存。但是由于数组永远不会离开范围,因此发送方永远不会自动删除字符串。您必须在收到字符串后主动清除字符串。对于这个解决方案,堆栈上会有一些恒定的开销。
或者(我认为更好,因为不存在碎片),您可以使用全局字符缓冲区之类的东西,保留用于分配正在传输的消息。在入队之前,将新消息(c 样式的空终止字符串)附加到当前缓冲区中的最后一条消息之后。队列应该包含指向 char 数组中消息的指针。
在分配一些新消息之前,您必须始终测试缓冲区中是否有空间用于字符串。
我这样做的方法是拥有一个全局“已接收”指针,工作人员将在读取消息时更新。当它完成处理时,它只是将指针移动到以空字符结尾的字符串。
然后,生产者将拥有另一个本地指针,用于记住它上次写东西的地方。由于接收到的指针是全局的,生产者总是可以计算出指针之间可用的“距离”,并知道可以将多少字符写入消息缓冲区。
这是一个简单的循环缓冲区,因此您需要通过添加读取和写入方法来处理溢出等。