我正在查看一些代码(实际上是 ArduPilot),将其用作我自己的东西的灵感。现在我想我发现了一个主要错误 - 但在大喊大叫之前 ;) 也许有人可以帮助我检查我是否误解了 C++。
有一个方法(我简化了):
void GCS_MAVLINK::update(void) {
// receive new packets
mavlink_message_t msg;
mavlink_status_t status;
// process received bytes
while (data_available()) {
uint8_t c = receive_data();
// Try to get a new message
if (parse_and_accumulate(c, &msg, &status)) {
handleMessage(&msg);
}
}
}
这是定期调用的。它从缓冲区读取数据直到耗尽,将其连同最终消息和状态结构的引用一起丢给外部解析函数以通过副作用进行更新,每次解析器看到消息完成时,都会使用该消息。
到目前为止一切顺利。如果缓冲区在消息中间运行为空会怎样?好的,其余的可能会在下一次预定调用时到达缓冲区。但是本地/堆栈分配会发生什么!!!消息和状态变量?据我所知,在此期间,它们可能已被堆栈使用中的各种垃圾覆盖。堆栈指针甚至可能已经移动。
在我出洋相之前,谁能帮我确认一下这里好像有大问题..
此外,如果我通过将 msg 和 status 变量设为静态来“修复”它,对于包含该方法的类的每个实例,它们仍然是独立的,对吗?
问候 索伦
最佳答案
What happens if the buffer runs empty in the middle of a message?
据推测,parse_and_accumulate
应该将传入的字节存储在某个地方,与输出消息参数分开,直到消息准备好;并且只写入该参数(如果是)。只有当该函数假定消息对象将在调用之间保留时才会出现错误,并且在没有看到该函数的情况下无法判断。
But what happens to the locally/stack allocated!!! msg and status variables?
正如您所说,它们在函数退出时被销毁。 如果 parse_and_accumulate
将它们用作持久性存储,那么您就会遇到错误,因为它们不是持久性的;希望它不会,但如果确实如此,几乎可以肯定该假设应该被修复。
Also, if I "fix" it by making the msg and status variables static, they will still be separate for each instance of the class containing the method, right?
将它们设为static
不会解决任何问题;由于不可重入,它可能只会导致模糊的错误。如果您没有向我们展示的功能是错误的,那么这就是需要修复的地方。
如果您将它们设为static
(无论是作为局部变量还是类成员),那么每一个都只有一个实例。如果它们确实需要持久化并与对象相关联,那么它们就必须是非静态类成员;但他们几乎肯定不应该。
关于c++ - 在我指责某人之前……这会奏效吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13931802/