cppcheck抱怨缓冲区超出范围。为什么以及如何修复?

时间:2016-03-30 07:13:25

标签: c cppcheck

下面的代码重现。在这种情况下,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?
    */

}

2 个答案:

答案 0 :(得分:2)

#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

答案 1 :(得分:1)

字符串文字"1.01A"为您提供指向六个字符数组的指针,您尝试从中读取15个字符。由于您读取的数据超出范围,因此您有未定义的行为,因为该内容是不确定