Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. can't use QVector::push_back on QUdpSocket
Qt 6.11 is out! See what's new in the release blog

can't use QVector::push_back on QUdpSocket

Scheduled Pinned Locked Moved Solved General and Desktop
20 Posts 5 Posters 2.6k Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • mzimmersM mzimmers

    @eyllanesc oh, geez, I keep forgetting that...thanks.

    Now, the QVector is actually a member variable; I need to use its contents outside of the routine this code is in. When the routine is called, it needs to clear the vector first. Do I understand that I need to call clear() and then squeeze() to avoid memory leaks? I'm using 5.14.2.

    Thanks again.

    B Offline
    B Offline
    Bonnie
    wrote on last edited by
    #4

    @mzimmers
    Before calling clear(), you should assure that the pointers have been freed.
    If not, using qDeleteAll() before clear().

    mzimmersM 1 Reply Last reply
    6
    • B Bonnie

      @mzimmers
      Before calling clear(), you should assure that the pointers have been freed.
      If not, using qDeleteAll() before clear().

      mzimmersM Offline
      mzimmersM Offline
      mzimmers
      wrote on last edited by
      #5

      @Bonnie ah yes, that's precisely what I need. Thanks, Bonnie.

      1 Reply Last reply
      0
      • mzimmersM Offline
        mzimmersM Offline
        mzimmers
        wrote on last edited by mzimmers
        #6

        OK, I thought I had a handle on this, but the compiler is telling me differently.

        Background: my app needs to maintain a list of "usable" network interfaces (definition of usable not important here). My thought was to create a struct:

        struct SockInfo
        {
            QNetworkInterface nic;
            QNetworkAddressEntry addr;
            QUdpSocket sockMulticast;
            QUdpSocket sockBroadcast;
        };
        

        and have a QList of these as a member variable. But...when I try to assign a value to an element, I get a compiler error (for the reasons given in prior posts).

        By converting the socket members to pointers, I can do this (this code is executed after the list is created):

        for (it = m_socks.begin(); it != m_socks.end(); ++it)
        {
        	pSockMulticast = new QUdpSocket;
        	SockInfo *p;
        	p = it;
        	p->sockMulticast = pSockMulticast;
        

        But this doesn't seem right -- I don't want a new socket; I want to alter the value of an entry in my list.

        So...I guess I don't really understand this after all. Any explanations, or ideas on doing this better, are most welcome.

        Thanks...

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #7

          Hi,

          In what way do you want to alter them ?

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          mzimmersM 1 Reply Last reply
          0
          • SGaistS SGaist

            Hi,

            In what way do you want to alter them ?

            mzimmersM Offline
            mzimmersM Offline
            mzimmers
            wrote on last edited by
            #8

            @SGaist one example is that the nic and addr will be set at app startup, but the sockets won't be filled in until later. Plus, if I need to add a connected socket to the struct, and that sock gets disconnected, I need to alter the stored data to reflect that.

            1 Reply Last reply
            0
            • eyllanescE Offline
              eyllanescE Offline
              eyllanesc
              wrote on last edited by
              #9

              @mzimmers Use

              struct SockInfo
              {
                  QNetworkInterface nic;
                  QNetworkAddressEntry addr;
                  QUdpSocket *sockMulticast;
                  QUdpSocket *sockBroadcast;
              };
              

              On the other hand I recommend you review your basic concepts of C++

              If you want me to help you develop some work then you can write to my email: e.yllanescucho@gmal.com.

              mzimmersM 1 Reply Last reply
              1
              • eyllanescE eyllanesc

                @mzimmers Use

                struct SockInfo
                {
                    QNetworkInterface nic;
                    QNetworkAddressEntry addr;
                    QUdpSocket *sockMulticast;
                    QUdpSocket *sockBroadcast;
                };
                

                On the other hand I recommend you review your basic concepts of C++

                mzimmersM Offline
                mzimmersM Offline
                mzimmers
                wrote on last edited by
                #10

                @eyllanesc said in can't use QVector::push_back on QUdpSocket:

                On the other hand I recommend you review your basic concepts of C++

                Can you elaborate?

                1 Reply Last reply
                0
                • eyllanescE Offline
                  eyllanescE Offline
                  eyllanesc
                  wrote on last edited by eyllanesc
                  #11

                  @mzimmers For example when using the copy constructor, clearly when doing your_struct.sockMulticast = foo you are trying to use the copy constructor since you are trying to copy the foo object to the sockMulticast attribute of the structure. And as I already pointed out the QObjects are not copyable, the copyable ones are the pointers. Or what is the difference of T with T* and understand that it is a pointer, and that you cannot assign a T* to T, nor T to T*.

                  If you want me to help you develop some work then you can write to my email: e.yllanescucho@gmal.com.

                  1 Reply Last reply
                  1
                  • mzimmersM Offline
                    mzimmersM Offline
                    mzimmers
                    wrote on last edited by
                    #12

                    OK, let's do this one step at a time. This is partial code from my header file:

                    struct SockInfo
                    {
                        QNetworkInterface nic;
                        QNetworkAddressEntry addr;
                        QUdpSocket *sockMulticast;
                        QUdpSocket *sockBroadcast;
                    };
                    class UdpSocket : public QObject
                    {
                    	QVector<SockInfo> m_socks;
                    }
                    

                    and here's where I create an entry:

                    void UdpSocket::getHostAddrs()
                    {
                            SockInfo sockInfo;
                    	sockInfo.nic = *it_qni;
                    	sockInfo.addr = addrEntries[i];
                    	m_socks.append(sockInfo);
                    }
                    

                    (Obviously some stuff is left out, but I think this demonstrates what I'm attempting.)

                    Does this look OK so far?

                    JonBJ 1 Reply Last reply
                    0
                    • mzimmersM mzimmers

                      OK, let's do this one step at a time. This is partial code from my header file:

                      struct SockInfo
                      {
                          QNetworkInterface nic;
                          QNetworkAddressEntry addr;
                          QUdpSocket *sockMulticast;
                          QUdpSocket *sockBroadcast;
                      };
                      class UdpSocket : public QObject
                      {
                      	QVector<SockInfo> m_socks;
                      }
                      

                      and here's where I create an entry:

                      void UdpSocket::getHostAddrs()
                      {
                              SockInfo sockInfo;
                      	sockInfo.nic = *it_qni;
                      	sockInfo.addr = addrEntries[i];
                      	m_socks.append(sockInfo);
                      }
                      

                      (Obviously some stuff is left out, but I think this demonstrates what I'm attempting.)

                      Does this look OK so far?

                      JonBJ Offline
                      JonBJ Offline
                      JonB
                      wrote on last edited by JonB
                      #13

                      @mzimmers
                      Yes :)

                      Notice that m_socks.append(sockInfo) copies your local SockInfo sockInfo variable as a new element into m_socks. That's why your QUdpSockets needed to be pointers.

                      Though if you'd like us (me) to nitpick (probably not!): reading your code I'd be surprised when I discover a class named UdpSocket holds an array of (pairs of) QUdpSocket, so a whole bunch of QUdpSockets. Maybe at least UdpSockets, or UdpSocketCollection/SockInfoCollection or similar, something to indicate it holds a bunch of them? Perhaps it's just me....

                      mzimmersM 1 Reply Last reply
                      1
                      • JonBJ JonB

                        @mzimmers
                        Yes :)

                        Notice that m_socks.append(sockInfo) copies your local SockInfo sockInfo variable as a new element into m_socks. That's why your QUdpSockets needed to be pointers.

                        Though if you'd like us (me) to nitpick (probably not!): reading your code I'd be surprised when I discover a class named UdpSocket holds an array of (pairs of) QUdpSocket, so a whole bunch of QUdpSockets. Maybe at least UdpSockets, or UdpSocketCollection/SockInfoCollection or similar, something to indicate it holds a bunch of them? Perhaps it's just me....

                        mzimmersM Offline
                        mzimmersM Offline
                        mzimmers
                        wrote on last edited by
                        #14

                        @JonB thanks for the confirmation, and I agree entirely about the unfortunate name of this class; that will get remedied.

                        In looking over an earlier post of mine, I think I caused some confusion about what I was originally doing. In my struct, I had converted the QUdpSocket elements to pointers; I just didn't post the code. Mea culpa.

                        I'm still having some difficulty; unfortunately, my VPN is down, so I can't post code right now. I'll post code when I can, but the essence is, I couldn't make a QVector of SockInfo. I had to make a QVector of Sockinfo *. Apart from seeming like an unnecessary level of indirection, it also made the iterator code uglier than farm subsidies.

                        Anyway, like I said, I'll post more code when I can. Thanks...

                        JonBJ 1 Reply Last reply
                        -1
                        • mzimmersM mzimmers

                          @JonB thanks for the confirmation, and I agree entirely about the unfortunate name of this class; that will get remedied.

                          In looking over an earlier post of mine, I think I caused some confusion about what I was originally doing. In my struct, I had converted the QUdpSocket elements to pointers; I just didn't post the code. Mea culpa.

                          I'm still having some difficulty; unfortunately, my VPN is down, so I can't post code right now. I'll post code when I can, but the essence is, I couldn't make a QVector of SockInfo. I had to make a QVector of Sockinfo *. Apart from seeming like an unnecessary level of indirection, it also made the iterator code uglier than farm subsidies.

                          Anyway, like I said, I'll post more code when I can. Thanks...

                          JonBJ Offline
                          JonBJ Offline
                          JonB
                          wrote on last edited by
                          #15

                          @mzimmers
                          My thought would be that the members of SockInfo you show are copyable (pointers to all QObjects now), so I would have expected QVector<SockInfo> m_socks; to be OK.

                          mzimmersM 2 Replies Last reply
                          0
                          • JonBJ JonB

                            @mzimmers
                            My thought would be that the members of SockInfo you show are copyable (pointers to all QObjects now), so I would have expected QVector<SockInfo> m_socks; to be OK.

                            mzimmersM Offline
                            mzimmersM Offline
                            mzimmers
                            wrote on last edited by
                            #16

                            @JonB actually, that's not quite how I did it. I made the QUdpSocket members pointers, but not the other members. Perhaps this was my undoing.

                            JonBJ 1 Reply Last reply
                            0
                            • mzimmersM mzimmers

                              @JonB actually, that's not quite how I did it. I made the QUdpSocket members pointers, but not the other members. Perhaps this was my undoing.

                              JonBJ Offline
                              JonBJ Offline
                              JonB
                              wrote on last edited by
                              #17

                              @mzimmers Show code when you're ready :)

                              1 Reply Last reply
                              0
                              • JonBJ JonB

                                @mzimmers
                                My thought would be that the members of SockInfo you show are copyable (pointers to all QObjects now), so I would have expected QVector<SockInfo> m_socks; to be OK.

                                mzimmersM Offline
                                mzimmersM Offline
                                mzimmers
                                wrote on last edited by
                                #18

                                @JonB said in can't use QVector::push_back on QUdpSocket:

                                @mzimmers
                                My thought would be that the members of SockInfo you show are copyable (pointers to all QObjects now), so I would have expected QVector<SockInfo> m_socks; to be OK.

                                You're right -- that is OK; I don't know what my problem was, but it was something else (I need to quit working late at night).

                                Here's the code -- preliminary testing indicates it's working, but I invite all critique/comments.

                                struct SockInfo
                                {
                                    QNetworkInterface nic;
                                    QNetworkAddressEntry addr;
                                    QUdpSocket *sockMulticast;
                                    QUdpSocket *sockBroadcast;
                                };
                                class UdpSocket : public QObject
                                {
                                private:
                                    QVector<SockInfo> m_socks;
                                }
                                // creating the list, and populating some of the members.
                                    QList<QNetworkAddressEntry> addrs; 
                                    QList<QNetworkAddressEntry>::iterator addr;
                                	addrs = nic->addressEntries();
                                
                                	// for each address entry
                                	for (addr = addrs.begin(); addr != addrs.end(); ++addr)
                                	{
                                		qha = addr->ip();
                                		if (qha.protocol() == QAbstractSocket::IPv4Protocol) // currently ignoring IP6 addresses.
                                		{
                                			sockInfo = new SockInfo;
                                			sockInfo->nic = *nic;
                                			sockInfo->addr = *addr;
                                			m_socks.append(*sockInfo);
                                			break;
                                		}
                                	}
                                // updating the list.
                                    QVector<SockInfo>::iterator sock;
                                    for (sock = m_socks.begin(); sock != m_socks.end(); ++sock)
                                    {
                                        pSockMulticast = new QUdpSocket;
                                        pSockBroadcast = new QUdpSocket;
                                        sock->sockMulticast = pSockMulticast;
                                        sock->sockBroadcast = pSockBroadcast;
                                ...
                                

                                Thanks...

                                JonBJ 1 Reply Last reply
                                0
                                • mzimmersM mzimmers

                                  @JonB said in can't use QVector::push_back on QUdpSocket:

                                  @mzimmers
                                  My thought would be that the members of SockInfo you show are copyable (pointers to all QObjects now), so I would have expected QVector<SockInfo> m_socks; to be OK.

                                  You're right -- that is OK; I don't know what my problem was, but it was something else (I need to quit working late at night).

                                  Here's the code -- preliminary testing indicates it's working, but I invite all critique/comments.

                                  struct SockInfo
                                  {
                                      QNetworkInterface nic;
                                      QNetworkAddressEntry addr;
                                      QUdpSocket *sockMulticast;
                                      QUdpSocket *sockBroadcast;
                                  };
                                  class UdpSocket : public QObject
                                  {
                                  private:
                                      QVector<SockInfo> m_socks;
                                  }
                                  // creating the list, and populating some of the members.
                                      QList<QNetworkAddressEntry> addrs; 
                                      QList<QNetworkAddressEntry>::iterator addr;
                                  	addrs = nic->addressEntries();
                                  
                                  	// for each address entry
                                  	for (addr = addrs.begin(); addr != addrs.end(); ++addr)
                                  	{
                                  		qha = addr->ip();
                                  		if (qha.protocol() == QAbstractSocket::IPv4Protocol) // currently ignoring IP6 addresses.
                                  		{
                                  			sockInfo = new SockInfo;
                                  			sockInfo->nic = *nic;
                                  			sockInfo->addr = *addr;
                                  			m_socks.append(*sockInfo);
                                  			break;
                                  		}
                                  	}
                                  // updating the list.
                                      QVector<SockInfo>::iterator sock;
                                      for (sock = m_socks.begin(); sock != m_socks.end(); ++sock)
                                      {
                                          pSockMulticast = new QUdpSocket;
                                          pSockBroadcast = new QUdpSocket;
                                          sock->sockMulticast = pSockMulticast;
                                          sock->sockBroadcast = pSockBroadcast;
                                  ...
                                  

                                  Thanks...

                                  JonBJ Offline
                                  JonBJ Offline
                                  JonB
                                  wrote on last edited by JonB
                                  #19

                                  @mzimmers
                                  Briefly:

                                          sockInfo = new SockInfo;
                                          m_socks.append(*sockInfo);
                                  

                                  Unless the sockinfo variable used here is a member variable of the class and you delete it in class destructor, or maybe you delete it in omitted code, this leaks. The sockinfo = new SockInfo instance is not itself being put in m_socks with m_socks.append(*sockInfo);, that copies it. Why do you new your SockInfos at all? If you are not intending this, you could have had:

                                  QSockInfo sockinfo;
                                  m_socks.append(sockInfo);
                                  

                                  It's OK to use a local/stack variable which goes out of scope because m_socks.append(sockInfo) is storing a copy of it.

                                  Separately

                                          sock->sockMulticast = pSockMulticast;
                                          sock->sockBroadcast = pSockBroadcast;
                                  

                                  If you are updating, what are you doing about the sock->sockMulticast/Broadcast which is currently there, which itself was previously newed here & elsewhere? Maybe that's in your omitted code.

                                  1 Reply Last reply
                                  1
                                  • mzimmersM Offline
                                    mzimmersM Offline
                                    mzimmers
                                    wrote on last edited by mzimmers
                                    #20

                                    I can see that I need to rename several variables...it seems like I actually tried to make this confusing.

                                    I left out the code that ties all this together. Whenever the main routine is invoked, it first calls this:

                                    void UdpSocket::cleanup()
                                    {
                                        QVector<SockInfo>::iterator it;
                                    
                                        for (it = m_socks.begin(); it != m_socks.end(); ++it)
                                        {
                                            if (it->sockMulticast->isValid())
                                            {
                                                delete it->sockMulticast;
                                            }
                                            if (it->sockBroadcast->isValid())
                                            {
                                                delete it->sockBroadcast;
                                            }
                                        }
                                        qDeleteAll(m_socks.begin(), m_socks.end());
                                        m_socks.clear();
                                    

                                    ...and then calls the code that creates the list, and then calls the code that creates the QUdpSockets that go into that list. So, I think I'm good on memory leaks (but of course I could be wrong).

                                    Your point about using a struct instead of a pointer to a struct is well-taken; I've changed that.

                                    Thanks...

                                    EDIT: since no one else commented on my implementation, I'm going to assume that it's tolerable. Marking thread as solved. Thanks to all who helped.

                                    1 Reply Last reply
                                    0

                                    • Login

                                    • Login or register to search.
                                    • First post
                                      Last post
                                    0
                                    • Categories
                                    • Recent
                                    • Tags
                                    • Popular
                                    • Users
                                    • Groups
                                    • Search
                                    • Get Qt Extensions
                                    • Unsolved