QByteArray::data() return value analysis, the char* assignment in the structure crashes

This is a bug analysis record encountered when using QByteArray

scene

  • When programming with QTcpSocket, a custom structure is used for data communication. The structure is as follows, where char* load is the address of the message body. In actual use, after using readALL to read the data stream, subpackage and group the package. When using the char* QByteArray::data interface to assign a value to load, the program will crash.
typedef struct
{
    
    
    unsigned int send_id;       // 发送方的ID(网络的IP、SRIO的ID)
    unsigned int recv_id;       // 接收方的ID(网络的IP、SRIO的ID)
    unsigned int msg_type : 8;  // 消息类型
    unsigned int len : 24;      // 消息长度,字节数
    unsigned int conn_type: 8;  // 连接类型,TCP、UDP等
    unsigned int pkg_num : 8;   // 总的包数(用于组包传输)
    unsigned int pkg_idx : 8;   // 子包索引(用于组包传输),从1计数
    unsigned int rsvd : 8;      // 保留位
    unsigned int check_sum;     // 校验位
    char* load;                 // 消息体地址
} DispCtrlMsg;

test program

Obviously it is the assignment of a char* pointer, but the program crashes; directly defining a char* pointer for assignment fails.

int main(int argc, char *argv[])
{
    
    
    QCoreApplication a(argc, argv);

    const int headLength = sizeof(DispCtrlMsg) - sizeof(char*);

    QByteArray str;
    str.resize(26);
    for(int i=0;i<str.size();i++){
    
    
        str[i]='a';
    }
    DispCtrlMsg *msg = new DispCtrlMsg();
    msg = (DispCtrlMsg*)str.left(headLength).data();

    int len = str.size();
    QByteArray r = str.right(len - headLength);
    cout << r.data() << endl;
    cout <<"1) "<< hex<<&msg->load <<endl;
//    msg->load = new char[1]; //注释这一行即崩溃。
    cout <<"2) "<< hex<<&msg->load <<endl;
    msg->load = r.data();
    cout <<"3) "<< hex<<&msg->load << endl;
    cout <<"4) "<< hex<<msg->load << endl;
    cout <<"5) "<< sizeof(msg->load) <<endl;

    char *c = r.data();
    cout <<"direct char* "<< c <<endl;


    delete msg->load;
    return a.exec();
}
  • The test result is shown in the figure, comment out, after new char[1], the program will crash. The length of new char[] only needs to be greater than or equal to 1.
    Insert picture description here

Temporary solution

  • When using the pointer assignment in the structure, use new or malloc to copy the content instead of using pointer assignment to point to the source.

msg->load is just a pointer, it can point to a character or a string. However, this method will lead to resource leakage. Because the new char is not used, and because msg->load no longer points to the space of this character, there is no chance that it will be released again, so this 1-bit space is a resource leak.

Reason for adding:

In the forced type conversion,
the length of QByteArray r = str.right(len-headLength); r is less than the length of the structure. Therefore, the char* load in the structure does not allocate space. Therefore, the program illegally accesses the memory. collapse.

Solutions

Create a structure object, or use malloc to allocate space for the structure pointer. The method of copying is adopted when reading data.

Guess you like

Origin blog.csdn.net/u013894391/article/details/100585221