QByteArray :: análisis de valor de retorno de datos (), la asignación char * en la estructura se bloquea

Este es un registro de análisis de errores encontrado al usar QByteArray

escena

  • Cuando se programa con QTcpSocket, se utiliza una estructura autodefinida para la comunicación de datos, la estructura es la siguiente, donde char * load es la dirección del cuerpo del mensaje. En uso real, después de usar readALL para leer el flujo de datos, subpaquete y agrupe el paquete. Cuando se usa la interfaz char * QByteArray :: data para asignar un valor a cargar, el programa se bloqueará.
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;

Programa de prueba

Obviamente, es la asignación de un puntero char *, pero el programa falló; la definición directa de un puntero char * para la asignación falló.

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();
}
  • El resultado de la prueba se muestra en la figura, comentar, después de un nuevo carácter [1], el programa se bloqueará. La longitud del nuevo carácter [] solo debe ser mayor o igual a 1.
    Inserte la descripción de la imagen aquí

Solución temporal

  • Cuando use la asignación de puntero en la estructura, use new o malloc para copiar el contenido en lugar de usar la asignación de puntero para apuntar a la fuente.

msg-> load es solo un puntero, puede apuntar a un carácter o una cadena. Sin embargo, este método provocará una fuga de recursos. Debido a que el nuevo carácter no se usa y debido a que msg-> load ya no apunta al espacio de este carácter, no hay posibilidad de que se libere nuevamente, por lo que este espacio de 1 bit es una pérdida de recursos.

Razón para agregar:

En la conversión de tipo forzada,
la longitud de QByteArray r = str.right (len-headLength); r es menor que la longitud de la estructura. Por lo tanto, la carga char * en la estructura no asigna espacio. Por lo tanto, el programa accede ilegalmente a la memoria. colapso.

Soluciones

Cree un objeto de estructura o utilice malloc para asignar espacio para el puntero de estructura. El método de copia se adopta al leer datos.

Supongo que te gusta

Origin blog.csdn.net/u013894391/article/details/100585221
Recomendado
Clasificación