Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

What does this serialization technique actually do?



  • The examples I've found in this site, cited some examples with this type of code:

    struct UnitStruct {
        UnitStruct(qint32 foo = 0) : data(foo) {}
        qint32 data;
    };
    
    QDataStream& operator<<(QDataStream& out, const UnitStruct* foo) { out << foo->data; return out;  }
    QDataStream& operator>>(QDataStream& in, UnitStruct*& foo) { foo = new UnitStruct(); in >> foo->data; return in;  }
    

    and I've modified it to use in the class, which I want to exchange between QTcpSocket and QTcpServer :

    class Message : public QObject
    {
        Q_OBJECT
        Property(QString, name)
        Property(int, age)
    
        friend QDataStream& operator<<(QDataStream& out, Message& foo) {
            out << foo.name();
            out << foo.age();
            return out;
        }
        friend QDataStream& operator>>(QDataStream& in, Message& foo) {
            in >> foo.name();
            in >> foo.age();
            return in;
        }
    };
    

    and it works for exchanging both a single Message object or a QVector<Message*>. For the single Message transmission I've no problem in understanding what's going on BUT for QVector<Message*> I'm not quite sure yet what it does on the Server side! From my Client, here's how I'm sending data to the Server:

    void MainVM::send()
    {
        QVector<Message*> messages;
        for(int i = 0; i < 5; i++){
            auto m = new Message();
            m->setname("Some name " + QString::number(i));
            m->setage(i + 100);
            messages.push_back(m);
        }
        QByteArray *arr = new QByteArray();
        QDataStream stream(arr, QIODevice::WriteOnly);
    
        stream << messages;
        socket->write(*arr);
        qDeleteAll(messages);
        delete arr;
    }
    

    and on the Server side, this is what I've right now:

    void MainVM::read()
    {
        auto client = static_cast<QTcpSocket*>(sender());
        QDataStream stream(client->readAll());
        stream >> m_messages;
        emit messagesChanged();
    }
    

    m_messages is a QVector<Message*> . First, I've QDataStream stream(client->readAll());, does this stream store the data on stack or heap? Second, stream >> m_messages;, does it create those 5 Message objects, sent by Client, on heap?



  • @Emon-Haque
    In a word: in QVector<> variable; the vector itself is stored on the stack, but the vector elements are allocated on the heap. Same for QDataStream variable;: variable is on the stack, data read in is stored on the heap. This of course allows for a small space allocation on the stack for the variable, while the large actual data is only limited by heap.



  • @Emon-Haque
    In a word: in QVector<> variable; the vector itself is stored on the stack, but the vector elements are allocated on the heap. Same for QDataStream variable;: variable is on the stack, data read in is stored on the heap. This of course allows for a small space allocation on the stack for the variable, while the large actual data is only limited by heap.



  • @JonB , is it same for QByteArray as well? For theQByteArray array, the array is on stack but the data in the array is on heap.



  • @Emon-Haque
    Absolutely yes! And the same is also true for QString. Some of this can be seen in https://doc.qt.io/qt-5/containers.html#the-container-classes, Qt "containers" work this way. And in https://doc.qt.io/qt-5/shared.html, Qt "shared data" work this way too. Think of all of these classes as having a "small" variable (on the stack) holding a couple of bits of information plus a pointer to the actual content data, held elsewhere (on the heap).


Log in to reply