0

我正在查看一些代码(实际上是 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 变量设为静态来“修复”它,它们对于包含该方法的类的每个实例仍然是分开的,对吧?

问候索伦

4

3 回答 3

3

What happens if the buffer runs empty in the middle of a message?

Presumably, parse_and_accumulate is supposed to store the incoming bytes somewhere, separately from the output message parameter, until a message is ready; and only write to that parameter if it is. There's only an error if that function assumes that the message object will be preserved between calls, and without seeing the function there's no way to tell.

But what happens to the locally/stack allocated!!! msg and status variables?

As you say, they are destroyed when the function exits. If parse_and_accumulate has used them as persistent storage, then you have a bug since they are not persistent; hopefully, it doesn't, but that assumption is almost certainly what should be fixed if it does.

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?

Making them static won't fix anything; it will probably just cause obscure bugs due to non-reentrancy. If the function you haven't shown us is wrong, then that's what needs fixing.

If you make them static (whether as local variables or class members) then there will only be one instance of each. If they did need to be persistent, and associated with the object, then they would have to be non-static class members; but they almost certainly shouldn't be.

于 2012-12-18T11:25:20.500 回答
0

Before I make a fool of myself, can someone help me confirm that there seems to be a major problem here..

There may or may not be a problem. It's really impossible to tell with just the code you show.

What happens if the buffer runs empty in the middle of a message? OK the rest will probably have arrived to the buffer at next scheduled invocation.

Before claiming that there is a bug, you need to make sure that this can actually happen. It doesn't look like the code you show has been written to deal with this, but maybe it doesn't need to?

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?

No, they won't. They will also make your code non-reentrant and not thread-safe.

于 2012-12-18T11:22:53.943 回答
0

好的,在再次查看 parse_and_accumulate 的来源之后,我现在看到它确实跨调用存储数据。参数结构仅用于将完成的消息返回到..

所以我的坏 - 对不起。谢谢您的帮助!

于 2012-12-19T20:51:34.837 回答