Qt5.3.2 QList losing QString contents between assignment and use
-
I am working with SmtpClient for Qt, Copyright (c) 2011-2012 - Tőkés Attila
I am using QtCreator under Ubuntu.
The code is creating "To" structures and adding them to a QList. To goes out of scope and is no longer valid, so if the QList is only making a list of pointers, then the behavior makes sense. On the other hand, this is code that supposedly worker (under Qt 4.8?; possibly not Ubuntu), so it must just be a matter of forcing a deeper copy. Suggestions?The code has a class, EmailAddress, which has private members:
QString name;
QString address;The code defines a list of recipients:
QList<EmailAddress*> recipientsTo, recipientsCc, recipientsBcc;I am adding recipients (only one for now). I tried creating "to" from two Qstrings. In an attempt to fix the issue I am having, I also tried using char [idx][128] (as below) to initialize with the same effect. My calling code uses:
int idx; for (idx=0; idx<mp.nRecpt; idx++) { EmailAddress to(mp.RcptAddr[idx] , mp.RcptName[idx]); message.addTo(&to); }
NOTE: to loses scope here and the only reason I still see values in message is probably that nothing has overwritten the ghost of the values on the stack yet. The called library uses:
void MimeMessage::addTo(EmailAddress* rcpt) {
this->recipientsTo << rcpt;
}After this call the debugger shows the correct strings in "this" (message) for address and name. Inside the loop - where "to" is still in scope - I see:
Locals
...
message @0xbff07efc MimeMessage
...
recipientsTo <1 items> QList<EmailAddress*>
[0] @0xbff07fe0 EmailAddress
[QObject] @0xbff07fe0 QObject
[methods] <0 items>
[properties] <more than 0 items>
[signals] <0 items>
address "jandle@..." QString
name "Jeff ..." QString
staticMetaObject @0xb7741a3c QMetaObject
sender @0xbff07eec EmailAddress
subject "" QString
...
to @0xbff07fe0 EmailAddress
[QObject] @0xbff07fe0 QObject
[methods] <0 items>
[properties] <more than 0 items>
[signals] <0 items>
address "jandle@..." QString
name "Jeff ..." QString
staticMetaObject @0xb7741a3c QMetaObjectI perform a few more assignments to message, after which the fields in message are still valid. As I said above, I am guessing it's just that "to" is still on the stack even if it went out of scope, since "to" is no longer in the Locals list. Then I execute the calls to send the email.
// Now the email can be sent if (!smtp.connectToHost()) { qDebug() << "Failed to connect to host!" << endl; return -1; } if (!smtp.login()) { qDebug() << "Failed to login!" << endl; return -2; } if (!smtp.sendMail(message)) { qDebug() << "Failed to send mail!" << endl; return -3; } smtp.quit(); return 0;
After smtp.connectToHost() the recipient fields are no longer valid. I am guessing this is because the function call used the stack and wiped out "to". This makes me thing I just need a deeper copy on QList<>.
Locals message @0xbff07efc MimeMessage
...
recipientsTo <1 items> QList<EmailAddress*>
[0] @0xbff07fe0 EmailAddress
[QObject] @0xbff07fe0 QObject
[methods] <0 items>
[properties] <more than 0 items>
[signals] <0 items>
address <not accessible> QString
name <not accessible> QString
staticMetaObject @0xb7741a3c QMetaObject -
int idx;
for (idx=0; idx<mp.nRecpt; idx++)
{
EmailAddress to(mp.RcptAddr[idx] , mp.RcptName[idx]);
message.addTo(&to);
}Object "to" is local to the loop, so when the end of the loop is reached, the destructor gets called and data is undefined.
This shall work …
int idx;
for (idx=0; idx<mp.nRecpt; idx++)
{
EmailAddress *to = new EmailAddress(mp.RcptAddr[idx] , mp.RcptName[idx]);
message.addTo( to);
} -
Thanks. I wasn't sure if QList made copies of data or copies of pointers. This is the sort of thing I assumed it was. Of course this code will ultimately run on an embedded system for indefinite periods, so i was hoping to let Qt do my memory clean up.
if I use "new" for *to is added to the QList, I assume I have to walk the list and delete all of them after sending the email (certainly not after assigning them!)
-
Thanks. I wasn't sure if QList made copies of data or copies of pointers. This is the sort of thing I assumed it was. Of course this code will ultimately run on an embedded system for indefinite periods, so i was hoping to let Qt do my memory clean up.
if I use "new" for *to is added to the QList, I assume I have to walk the list and delete all of them after sending the email (certainly not after assigning them!)
If you do not like that cleanup or if it is too hard to decide whether to free the memory you can use one oft these.
QSharedData QSharedDataPointer QSharedPointer
I have used QSharedDataPointer (but not the others so far), and it seems to work nice.