conflicting instantiation - memory leak?

I've been lurking about these questions for awhile and learned alot but recently have come up against a problem that I don't understand. I'm using Qt and need to create/replace a QMovie object in various class methods (which is ultimately set in a QLabel). I've defined the object using the new keyword. Thus in the header I have

QMovie * movie;

For simplicity I'll put the equivalent code in a single method. This is equivalent to the two lines of code

QMovie * movie = new QMovie(QByteArray1,this);
QMovie * movie = new QMovie(QByteArray2,this);

This works (I don't know why) but since it is a repeated operation I worry about memory leaks. It appears that the second definition replaces the first one successfully but since presumably they each have diffeent pointers I don't know how to delete the pointer to the first definition. I delete movie in the class destructor but don't know if it will delete everything. Anyone know what is happening here?

P.S. I do this because the only way (I've found in Qt) to create a QMovie object using data in a QByteArray (which was downloaded from the web) is to use the QMovie constructor. If I just wanted to replace the current movie data with new data from a file I could use the method

movie->setFileName(fileName);

but this isn't an option when using binary data. Note: QMovie also has a constructor that has a filename instead of a QByteArray as an argument. Using filenames also works using the above code and is easier to test.

Any help will be appreciated.

Answers


Generally speaking, if anything derived from QObject is contained in a hierarchy of QObjects, they are automatically destructed when the parent is destructed. In your case, you are giving the QMovie a parent through the constructor, so the cleanup should be taken care of for you. If you want to confirm, derive a class from QMovie, implement a destructor that prints a message, and make sure it is called when you expect (i.e. when the parent is destructed).


The idiomatic way of doing it in C would be:

  1. Initialize the pointer to zero.

  2. Before assigning to it, free() the object pointed to by the old pointer. You do not need to check for zero: free() on a zero pointer is a safe no-op.

  3. free() the object when the pointer goes out of scope.

The idiomatic way of doing it in Qt is even simpler.

  1. Use QSharedPointer<> or QScopedPointer<>. It will automatically delete the pointed-to object when it goes out of scope.

    • If only one pointer is supposed to own the object, use QScopedPointer. It will delete the pointed-to object when it goes out of scope. This is similar to std::auto_ptr.

    • For shared ownership, use QSharedPointer. It will delete the pointed-to object when the last QSharedPointer that points to it goes out of scope/gets destroyed.

  2. For QScopedPointer, use reset(T*other) method to assign a new value to the pointer. For QSharedPointer, you can only assign other shared pointers to it, like QSharedPointer a = QSharedPointer(new Class);

In either case, any previously pointed-to object will be deleted.

Thus:

class MyClass {
  QScopedPointer<QMovie> movie1;
  QSharedPointer<QMovie> movie2;
public:
  MyClass {} // note: no need for any special initialization
  void method() {
    movie1.reset(new QMovie(...));
    movie2 = QSharedPointer(new QMovie(...));
  }
};

This is completely safe. You can call MyClass::method() as often as you wish with no memory leaks. At any point in time, MyClass will keep alive at most two QMovie objects.


QMovie * movie = new QMovie(QByteArray1,this);
QMovie * movie = new QMovie(QByteArray2,this);

If these two lines are in the same .cc file, then you will get a redefinition error. If the two lines are in separate .cc files, then when you build the executable, you will get a multiple definition error. But, your question has this wording:

I'm using Qt and need to create/replace a QMovie object in various class methods (which is ultimately set in a QLabel)

If the QMovie object resides in different classes, you don't have a memory leak, because each class's pointer is different from another's.

However, if your intention is that all the classes refer to the same QMovie instance, you will need to find a way to pass the instance to each object. Alternatively, you would have them all refer to the same one (i.e., using the singleton pattern).


Need Your Help

Android paint/canvas issue; drawing smooth curves

android android-canvas paint draw curvesmoothing

How do I get smooth curves instead of dots or circles, when I draw with my finger on the touch screen, in Android? I am using the following code-

laravel 5 routing in working app folder other than the examples that use the default 127.0.0.1 root

php html5 laravel

am trying to understand the laravel 5 routing bt its giving me headache.am using vagrant.in my routes.php i have the following: