如何防止缓冲区溢出/阵列溢出?

时间:2016-04-09 18:43:33

标签: c arrays embedded exception-safety memory-safety

我最近在编写自定义串行通信协议的代码。我所做的是,我使用接收数据的一部分(8/16位)来表示帧大小有多大。根据这些数据,我希望 没有数据可以遵循。我使用Crc接受或拒绝一个帧。但是我无法在Crc中包含帧长度数据,因为在接收端我应该知道在处理帧之前需要多少数据。

我遇到的问题是,这个帧长度数据偶尔会被破坏,它会使接收器接收到那么多字节,而接收阵列的大小要小得多。这破坏了连续存储器位置中存在的许多关键系统变量。

如何防止缓冲区溢出? 我对此的看法 1)如果超过某个值,则拒绝 framelength 数据。 2)使用限制最大值的数据类型。就像使用short将数组索引的范围限制为256个内存位置,并创建一个280字节的缓冲区。 3)在一个单独的位置分配内存,这样它就不会影响关键的系统变量。

我用来阻止卡在接收循环中的一件事是使用超时。但我忽略了这个问题的这个方面。 如果有时间来确认并重现问题,那么看起来很多,因为代码是更大的系统代码的一部分,我不是这里的专家。

一般如何安全地处理这类问题?

另外:使用数组时要遵循的一般注意事项或标准做法是什么,以防止它溢出?

2 个答案:

答案 0 :(得分:1)

有很多东西可以用来最小化这个问题,但是一般来说,没有任何一种尺寸适合的解决方案。您必须做出决定并了解如果出现问题并使您的系统能够处理它会发生什么。

您必须弄清楚最适合您系统的内容。例如,如果您从未期望消息大于256,则将缓冲区的大小声明为0xFF,将缓冲区的索引声明为uint8_t,您将永远无法超过它一次插入一个字节,因为索引将永远不会达到256并溢出回0.当然,如果发生这种情况,你会覆盖一些收到的数据,但crc检查应该在大多数情况下显示错误。

您可以做的另一件事是将数据长度与缓冲区最大值进行比较,如果超出缓冲区则不存储消息。因此,您可以直接拒绝任何数据长度过大且收到的消息,但不会存储数据。显然,如果数据长度经常损坏,那么你会遇到很多问题。

说实话,最好的方法是重新考虑您的自定义串行通信协议。这听起来不像是你遇到的错误很好。您可以在消息的开头和结尾处同步字节,以确保您实际上正在接收良好的数据和CRC整个消息没有问题,并定义将通过线路的最大数据包大小并发信号通知有多少数据包收到。如果通信协议不是很好,那么你必须从下往上重新考虑它。

答案 1 :(得分:1)

首先,检查帧错误,检查奇偶校验错误

第二,检查数据大小的大小。如果太大或太小,拒绝整个数据块

相关问题