C++, new, delete, constructors & Qt

Code junkies hangout here

Moderators: ChrisThornett, LXF moderators

C++, new, delete, constructors & Qt

Postby Biscuiteer » Mon Jan 18, 2010 4:49 pm

Hello all,

I've recently returned to C++ after a break of a few years and would like a few points clarifying about new and delete, as used in class constructors / destructors.

I understand that every single thing created using new, must be explicitly deleted before the program quits. Correct?

Following Qt's built in Address Book tutorials (as sadly all the tuxradar ones fail with segmentation faults) I note that even though the class constructor in question uses new to create dynamic objects, the destructor is left empty. Ok, that might be down to stripping down the code for the purposes of education but when I add delete commands to the destructor for each instance of new in the constructor, I run into trouble. See the annotations in the code.

Code: Select all
AddressBook::AddressBook(QWidget *parent)
    : QWidget(parent)
{
    QLabel *nameLabel = new QLabel(tr("Name"));
    nameLine = new QLineEdit; // nameLine declared as (private) pointer in class header file

    QLabel *addressLabel = new QLabel(tr("Address"));
    addressText = new QTextEdit; // addressText declared as (private) pointer in class header file

    QGridLayout *mainLayout = new QGridLayout;
    mainLayout->addWidget(nameLabel,0,0);
    mainLayout->addWidget(nameLine,0,1);
    mainLayout->addWidget(addressLabel,1,0, Qt::AlignTop);
    mainLayout->addWidget(addressText,1,1);

    setLayout(mainLayout);
    setWindowTitle(tr("Simple Address Book"));

}

AddressBook::~AddressBook()
{
//    delete nameLabel;     // <-- Compiler error: Out of scope
    delete nameLine;     // declared as private pointer in class header file
//    delete addressLabel;     // <-- Compiler error: Out of scope
    delete addressText;     // declared as private pointer in class header file
//    delete mainLayout;     // <-- Compiler error: Out of scope

}


Is there a memory leak if delete is not called for these objects, and if so, how to delete the ones that are declared out of scope in the destructor?

thanks
R
Biscuiteer
 
Posts: 4
Joined: Sun Dec 27, 2009 9:27 pm

Postby 1slipperyfish » Mon Jan 18, 2010 5:31 pm

hello i'm no c++ expert but should it not be
Code: Select all
AddressBook::~AddressBook()
{
//    delete nameLabel;     // <-- Compiler error: Out of scope
    delete nameLine[];     // declared as private pointer in class header file
//    delete addressLabel;     // <-- Compiler error: Out of scope
    delete addressText[];     // declared as private pointer in class header file
//    delete mainLayout[];     // <-- Compiler error: Out of scope

}

if that doesn't do it post so and i'll have fiddle but i learned it as [] , but you have to free all memory you use for every constructor you must have a de-constructor,
i was using this as reference but someone who is better than me might know different ?or if you could post the rest of the code? :D
hth :D
paul
i am a follower of the culture

Image
User avatar
1slipperyfish
Forum Jester
 
Posts: 2431
Joined: Mon May 09, 2005 2:52 pm
Location: wigan

Postby Ram » Mon Jan 18, 2010 5:33 pm

Wouldn't calling a destructor as

Code: Select all
~addressText();


work?

lubuntu LXDE 13.10 running on AMD Phenom II*4; ASUS Crosshair III Formula MB; 4 GB Ram.....
User avatar
Ram
LXF regular
 
Posts: 1676
Joined: Thu Apr 07, 2005 9:44 pm
Location: Guisborough

Postby Biscuiteer » Mon Jan 18, 2010 6:44 pm

1slipperyfish (troll): no that doesn't work. I don't use delete[] as I'm not trying to delete arrays.

Ram: Would I be correct to say that I shouldn't have to call class destructors, they should automatically be called?

My problem is one of scope, I think. Why does this work?

Code: Select all
// class definition (addressbook.h) exerpt:
#include <QtGui/QLineEdit>

class AddressBook : public QWidget
{
private:
    QLineEdit *nameLine;
}

//class methods exerpt:
#include "addressbook.h"

AddressBook::AddressBook(QWidget *parent)
    : QWidget(parent)
{
    nameLine = new QLineEdit;
    nameLine->setReadOnly(true);
}
AddressBook::~AddressBook()
{
    delete nameLine;
}


And why does the following not work
Code: Select all
// class definition (addressbook.h) exerpt:
#include <QtGui/QLabel>

class AddressBook : public QWidget
{
}

//class methods exerpt:
#include "addressbook.h"

AddressBook::AddressBook(QWidget *parent)
    : QWidget(parent)
{
    QLabel *nameLabel = new QLabel(tr("Name"));
}
AddressBook::~AddressBook()
{
    delete nameLabel;
}


is it purely because nameLine is declared in the class definition and nameLabel isn't?
Biscuiteer
 
Posts: 4
Joined: Sun Dec 27, 2009 9:27 pm

Postby spaceyhase » Mon Jan 18, 2010 7:51 pm

Yes, because 'nameLabel' only exists within the scope of the constructor (between the braces ;) ). The example doesn't feature 'nameLabel' though, are you adding it yourself? However, one thing to note here is that the 'ui' object has 'ownership' of these objects when they're constructed; it's counter-intuitive in a way but because 'ui' is deleted by the constructor, it will clean up the remaining objects for you :)
spaceyhase
LXF regular
 
Posts: 116
Joined: Mon Jun 30, 2008 12:07 pm

Postby Biscuiteer » Mon Jan 18, 2010 9:02 pm

spaceyhase - thank you! That makes sense now. I'm not adding 'nameLabel' myself, it appears in the version of the tutorial that's built into Qt Creator's help. I think that this is the same version here too.

Not quite sure what you mean about the 'ui' object though, do you mean the QWidget class that the AddressBook class is derived from? And quite what is it cleaning up automatically?
Biscuiteer
 
Posts: 4
Joined: Sun Dec 27, 2009 9:27 pm

Postby Ram » Mon Jan 18, 2010 10:19 pm

We construct a new AddressBook widget on the stack and invoke its show() function to display it. However, the widget will not be shown until the application's event loop is started. We start the event loop by calling the application's exec() function; the result returned by this function is used as the return value from the main() function. At this point, it becomes apparent why we instanciated AddressBook on the stack: It will now go out of scope. Therefore, AddressBook and all its child widgets will be deleted, thus preventing memory leaks.


That's the last part of Part 1 - Does that help..


PS. thanks for the link to 4.6 - I.ve got 4.5 install and only the first 4 part of this tutorial are there.

lubuntu LXDE 13.10 running on AMD Phenom II*4; ASUS Crosshair III Formula MB; 4 GB Ram.....
User avatar
Ram
LXF regular
 
Posts: 1676
Joined: Thu Apr 07, 2005 9:44 pm
Location: Guisborough

Postby Biscuiteer » Tue Jan 19, 2010 2:56 pm

Yes, that helps! Somehow I missed reading that the first time around,

thanks everyone,
R
Biscuiteer
 
Posts: 4
Joined: Sun Dec 27, 2009 9:27 pm


Return to Programming

Who is online

Users browsing this forum: No registered users and 0 guests