cppcheck 抱怨缓冲区被越界访问。为啥以及如何解决?

Posted

技术标签:

【中文标题】cppcheck 抱怨缓冲区被越界访问。为啥以及如何解决?【英文标题】:cppcheck complains Buffer is accessed out of bounds. Why and how do I fix?cppcheck 抱怨缓冲区被越界访问。为什么以及如何解决? 【发布时间】:2016-03-30 07:13:24 【问题描述】:

下面的代码重现。在这种情况下,cppcheck 报告越界错误是否正确?用memcpy在线报错。

#include <stdint.h>
#include <string.h>
#include <stdio.h>

typedef struct 
    uint32_t serial_number;
    uint8_t software_version[15];
 STATIC_HARDWARE_DATA;

typedef struct 
    uint16_t              result_code;  
    uint8_t               startup_type; 
    STATIC_HARDWARE_DATA  payment_data; 
 MSG_DETAILS;

int main() 

    MSG_DETAILS msg = 0;
    msg.result_code = 0;
    msg.startup_type = 2;
    msg.payment_data.serial_number = 0xAAAA;
    // on line below cppcheck says: Buffer is accessed out of bounds
    memcpy(msg.payment_data.software_version, "1.01A", 15);

    printf("%s", msg.payment_data.software_version);  // prints correct 1.01A

    /* in memory msg.payment_data.software_version is:
      '1', '.', '0', '1', 'A', '\0', '\0', '\0', '_', '\0', '_', 'n', '\0', 'a'

      The characters on end of array are unexpected?
    */


【问题讨论】:

使用1.01A的大小而不是15 【参考方案1】:
#include <stdint.h>
#include <string.h>
#include <stdio.h>

typedef struct 
    uint32_t serial_number;
    uint8_t software_version[15];
 STATIC_HARDWARE_DATA;

typedef struct 
    uint16_t              result_code;  
    uint8_t               startup_type; 
    STATIC_HARDWARE_DATA  payment_data; 
 MSG_DETAILS;

int main() 

    MSG_DETAILS msg = 0;
    msg.result_code = 0;
    msg.startup_type = 2;
    msg.payment_data.serial_number = 0xAAAA;
    // on line below cppcheck says: Buffer is accessed out of bounds
    memcpy(msg.payment_data.software_version, "1.01A", 6);//<-- size should be 6 including \0.

    printf("%s", msg.payment_data.software_version);  // prints correct 1.01A

    /* in memory msg.payment_data.software_version is:
      '1', '.', '0', '1', 'A', '\0', '\0', '\0', '_', '\0', '_', 'n', '\0', 'a'

      The characters on end of array are unexpected?
    */



o/p:
rabi@rabi-VirtualBox:~/rabi/c$ gcc gg.c 
rabi@rabi-VirtualBox:~/rabi/c$ ./a.out 
1.01A

【讨论】:

【参考方案2】:

字符串文字"1.01A" 为您提供了一个指向六个字符数组的指针,您尝试从中读取 15 个字符。由于您读取的数据越界,您就有未定义的行为,因为内容是不确定的

【讨论】:

当然没想到出处。这就解释了数组中的奇怪字符。

以上是关于cppcheck 抱怨缓冲区被越界访问。为啥以及如何解决?的主要内容,如果未能解决你的问题,请参考以下文章

缓冲区在 cppcheck 中被越界访问

cppcheck 报告“缓冲区访问越界”

cppcheck 在模板中使用时抱怨 unreadVariable

cppcheck 抱怨 c_str() 的危险使用。此调用后 c_str() 返回的值无效

内存访问越界——但为啥呢?

问答题