tags:

views:

749

answers:

5

What do you think? Is this correct or are there memory leaks?

Source:

#include <QList.h>
#include <boost/shared_ptr.hpp>
#include <iostream>

class A {
private:
    int m_data;
public:
    A(int value=0) { m_data = value; }
    ~A() { std::cout << "destroying A(" << m_data << ")" << std::endl; }
    operator int() const { return m_data; }
};

int _tmain(int argc, _TCHAR* argv[])
{
    QList<boost::shared_ptr<A> > list;
    list.append(boost::shared_ptr<A>(new A(6)));
    std::cout << int(*(list.at(0))) << std::endl;
    return 0;
}

Output:

6
destroying A(6)
A: 

It is difficult to suggest anything without knowing why the list of shared_ptrs of A objects exist in the first place.

Take a look at the ownership semantics of smart pointers. Maybe of help to you.

Some other things that can be improved:

1. Use initializer lists in ctor like:

class A {
 private:
   int m_data;
 public:
    A(int value=0) : m_data (value) {}
 // ....

2. int _tmain(int argc, _TCHAR* argv[]) is not a Standard signature;

Use

int main(int argc, char* argv[])

or just:

int main()
dirkgently
I'm not sure what you mean with your first point. Where should I use initializer lists?`_tmain` was the default when using the Visual Studio wizard but thank's for that hint!
Wolfgang Plaschg
_tmain(int argc, _TCHAR* argv[]) is a valid signature on VC++ :). It's a main method that takes either multibyte or unicode arguments, depending on a switch in VS.There's also a int wmain(int argc, wchar_t *argv[]).
Skurmedel
An implementation can provide N different signatures of main. The language Standard defines only two (I mentioned above).
dirkgently
Yes that's true. But as I said, it's perfectly valid on VC++.
Skurmedel
A: 

This code looks perfectly fine.

If you're seeking advice perhaps you could provide more info on the purpose of using shared_ptr with QList, there might be a "Qt" way of doing this without pulling the big guns such as shared_ptr.

Idan K
I was playing around with QList<A *> and when doing so you have to take care of the list elements by yourself. Which is annoying, obviously. I haven't found a Qt way for using smart pointers.
Wolfgang Plaschg
that's not entirely correct. you could use Qt's object ownership tree like layout, passing the QList as the owner of each object inserted to it. it's a very useful technique when working with Qt. read more about it here: http://doc.trolltech.com/4.5/objecttrees.html
Idan K
@daniel That's not a option here, as the parents and children have to be QObject subclasses for that to work. QList isn't a QObject so it's a no go even if A inherited from QObject.
Parker
true, totally forgot that QList isn't a QObject! this can still be useful though, depending on the context of using that QList.
Idan K
+1  A: 

It seems correct. Boost's shared_ptr is a reference counting pointer. Reference counting is able to reclaim memory if there are no circular references between objects. In your case, objects of class A do not reference any other objects. Thus, you can use shared_ptr without worries. Also, the ownership semantics allow shared_ptrs to be used in STL (and Qt) containers.

ahnurmi
A: 

If you're not using a smart pointer, you have to delete the list elements by yourself.

Source:

#include <QList.h>
#include <boost/shared_ptr.hpp>
#include <iostream>

class A {
private:
    int m_data;
public:
    A(int value=0) { m_data = value; }
    ~A() { std::cout << "destroying A(" << m_data << ")" << std::endl; }
    operator int() const { return m_data; }
};

int _tmain(int argc, _TCHAR* argv[])
{
    QList<A *> list;
    list.append(new A(6));
    std::cout << int(*(list.at(0))) << std::endl;
    return 0;
}

Output:

6

Not good.

Wolfgang Plaschg
Then just remove the "new" operator and the A objects will be deconstructed when the the QList is.
Parker
A: 

Qt 4.6 now comes with smart pointers, jfyi.

ShaChris23