Kampfgnom
28th September 2012, 11:13
Hi,
I want my classes to use QExplicitlySharedDataPointer for their shared data. Also I want several classes to reference each other.
We have ClassX and ClassY. ClassX maintains a QList<ClassY>. ClassY references exactly one ClassX. Both classes implement copy constructor and operator=(), like this:
ClassY::ClassY(const ClassY &other) :
QObject(other.parent()),
d( other.d )
{
}
ClassY &ClassY::operator =(const ClassY &other)
{
d = other.d;
return *this;
}
When we now use the following code to add/set the values, it leads to circular dependencies between the two classes:
void ClassY::setClassX(const ClassX &classX)
{
d->m_classX = classX;
}
void ClassX::addClassY(const ClassY &classY)
{
d->m_classYList.append(classY);
}
When we execute the following test, the shared data objects are never being destroyed and leak:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
ClassX x1;
ClassY y1;
x1.addClassY(y1);
y1.setClassX(x1);
return a.exec();
}
I create the output with the help of incremental IDs for each instance of ClassX, ClassY, ClassXPrivate and ClassYPrivate:
ClassXPrivate 0
ClassX 0
ClassXPrivate 1
ClassX 1
ClassYPrivate 0
ClassY 0
~ClassXPrivate 1
~ClassY 0
~ClassX 0
As you can see, ClassYPrivate 1 and ClassXPrivate 0 are never being destructed.
You may download the small example Qt Creator project from my dropbox: http://dl.dropbox.com/u/140012/sharedatatest.zip
I came across this behavious in the libtvdb (http://sourceforge.net/projects/libtvdb/) library, in which each Series has several Seasons, which has several Episodes. Each Season knows its Series and each Episode knows its Season and Series. This leads to HUGE memory leaks, if you scrape several hundred TV shows.
Am I right, with what I am saying? How would you solve this problem?
Greetings Niklas
I want my classes to use QExplicitlySharedDataPointer for their shared data. Also I want several classes to reference each other.
We have ClassX and ClassY. ClassX maintains a QList<ClassY>. ClassY references exactly one ClassX. Both classes implement copy constructor and operator=(), like this:
ClassY::ClassY(const ClassY &other) :
QObject(other.parent()),
d( other.d )
{
}
ClassY &ClassY::operator =(const ClassY &other)
{
d = other.d;
return *this;
}
When we now use the following code to add/set the values, it leads to circular dependencies between the two classes:
void ClassY::setClassX(const ClassX &classX)
{
d->m_classX = classX;
}
void ClassX::addClassY(const ClassY &classY)
{
d->m_classYList.append(classY);
}
When we execute the following test, the shared data objects are never being destroyed and leak:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
ClassX x1;
ClassY y1;
x1.addClassY(y1);
y1.setClassX(x1);
return a.exec();
}
I create the output with the help of incremental IDs for each instance of ClassX, ClassY, ClassXPrivate and ClassYPrivate:
ClassXPrivate 0
ClassX 0
ClassXPrivate 1
ClassX 1
ClassYPrivate 0
ClassY 0
~ClassXPrivate 1
~ClassY 0
~ClassX 0
As you can see, ClassYPrivate 1 and ClassXPrivate 0 are never being destructed.
You may download the small example Qt Creator project from my dropbox: http://dl.dropbox.com/u/140012/sharedatatest.zip
I came across this behavious in the libtvdb (http://sourceforge.net/projects/libtvdb/) library, in which each Series has several Seasons, which has several Episodes. Each Season knows its Series and each Episode knows its Season and Series. This leads to HUGE memory leaks, if you scrape several hundred TV shows.
Am I right, with what I am saying? How would you solve this problem?
Greetings Niklas