const function causes garbage collection crashes with QMap.
-
Hi,
I have a QMap containing instances of a fairly large class, lets say class A.
The parent class B (of which the QMap is a member variable) has a function that returns either a value or a reference to something inside A.
If the class B function is marked "const", it's call into QMap
e.g. qmap[key].someClassAfunction()
appears to make a copy of class A, before calling someClassAfunction(), even if someClassAfunction() is itself "const".
If the class B function call is in the same thread, this isn't a problem. But if called from another thread - just to look up a value in class A without making any changes - the garbage collection seems to crash the app due to the class A copy.
If I remove the "const" qualifier from the class B function, the call into QMap doesn't do a copy, but instead returns a reference. However this means I have to remove the "const" qualifier from someClassAfunction(), even if this class A function doesn't modify any class A internal state.
This seems very odd to me. Can anyone explain why calling into a QMap from a "const" function causes QMap to do a copy?
Thanks,
Michael -
Hi,
I have a QMap containing instances of a fairly large class, lets say class A.
The parent class B (of which the QMap is a member variable) has a function that returns either a value or a reference to something inside A.
If the class B function is marked "const", it's call into QMap
e.g. qmap[key].someClassAfunction()
appears to make a copy of class A, before calling someClassAfunction(), even if someClassAfunction() is itself "const".
If the class B function call is in the same thread, this isn't a problem. But if called from another thread - just to look up a value in class A without making any changes - the garbage collection seems to crash the app due to the class A copy.
If I remove the "const" qualifier from the class B function, the call into QMap doesn't do a copy, but instead returns a reference. However this means I have to remove the "const" qualifier from someClassAfunction(), even if this class A function doesn't modify any class A internal state.
This seems very odd to me. Can anyone explain why calling into a QMap from a "const" function causes QMap to do a copy?
Thanks,
Michael@mjsmithers
If I have understood/guessed. If you only want to read from aQMap
why not use
T QMap::value(const Key &key, const T &defaultValue = T()) const
Using
T &QMap::operator[](const Key &key)
is notconst
because it creates the key if it does not already exist.Is this relevant to your situation?
-
Hi,
I have a QMap containing instances of a fairly large class, lets say class A.
The parent class B (of which the QMap is a member variable) has a function that returns either a value or a reference to something inside A.
If the class B function is marked "const", it's call into QMap
e.g. qmap[key].someClassAfunction()
appears to make a copy of class A, before calling someClassAfunction(), even if someClassAfunction() is itself "const".
If the class B function call is in the same thread, this isn't a problem. But if called from another thread - just to look up a value in class A without making any changes - the garbage collection seems to crash the app due to the class A copy.
If I remove the "const" qualifier from the class B function, the call into QMap doesn't do a copy, but instead returns a reference. However this means I have to remove the "const" qualifier from someClassAfunction(), even if this class A function doesn't modify any class A internal state.
This seems very odd to me. Can anyone explain why calling into a QMap from a "const" function causes QMap to do a copy?
Thanks,
Michael@mjsmithers said in const function causes garbage collection crashes with QMap.:
the garbage collection seems to crash the app due to the class A copy.
Neither standard C++ nor Qt's C++ API (QML is another story) has garbage collection. An object is destroyed either when an auto scoped instance goes out of scope, or when a dynamically allocated instance is deleted. You can determine when this is occurs via the destructor.
-
@mjsmithers
If I have understood/guessed. If you only want to read from aQMap
why not use
T QMap::value(const Key &key, const T &defaultValue = T()) const
Using
T &QMap::operator[](const Key &key)
is notconst
because it creates the key if it does not already exist.Is this relevant to your situation?
@JonB said in const function causes garbage collection crashes with QMap.:
@mjsmithers
If I have understood/guessed. If you only want to read from aQMap
why not use
T QMap::value(const Key &key, const T &defaultValue = T()) const
Using
T &QMap::operator[](const Key &key)
is notconst
because it creates the key if it does not already exist.Is this relevant to your situation?
Thanks. The documentation says that QMap::value() returns the value, but doesn't say if it's a copy or a reference, so I'd assumed a copy. I'll do some more testing.
-
@JonB said in const function causes garbage collection crashes with QMap.:
@mjsmithers
If I have understood/guessed. If you only want to read from aQMap
why not use
T QMap::value(const Key &key, const T &defaultValue = T()) const
Using
T &QMap::operator[](const Key &key)
is notconst
because it creates the key if it does not already exist.Is this relevant to your situation?
Thanks. The documentation says that QMap::value() returns the value, but doesn't say if it's a copy or a reference, so I'd assumed a copy. I'll do some more testing.
@mjsmithers
Since it'sT QMap::value()
notT&
(orconst T&
) that's a copy not a reference? Docs stateQMap's key and value data types must be assignable data types.
I believe that tells you that the value must be copyable, and is copied.
-
@mjsmithers said in const function causes garbage collection crashes with QMap.:
the garbage collection seems to crash the app due to the class A copy.
Neither standard C++ nor Qt's C++ API (QML is another story) has garbage collection. An object is destroyed either when an auto scoped instance goes out of scope, or when a dynamically allocated instance is deleted. You can determine when this is occurs via the destructor.
@jeremy_k said in const function causes garbage collection crashes with QMap.:
@mjsmithers said in const function causes garbage collection crashes with QMap.:
the garbage collection seems to crash the app due to the class A copy.
Neither standard C++ nor Qt's C++ API (QML is another story) has garbage collection. An object is destroyed either when an auto scoped instance goes out of scope, or when a dynamically allocated instance is deleted. You can determine when this is occurs via the destructor.
Thanks. You're correct. I miss-characterised the crash. When I call function B (with 'const') from another thread, Qmap[] seems to copy class A then the app crashes when trying to read stuff from inside the class A. I'm guessing since the copy goes out of scope. I don't fully understand why but the solution appears to be removing all the const qualifiers.
That said, I'll experiment more with Qmap::value(), although it's not clear from the documentation if it returns a copy or a const reference. Class A has some dynamically allocated internal stuff which complicates matters.
Thanks again.
-
@jeremy_k said in const function causes garbage collection crashes with QMap.:
@mjsmithers said in const function causes garbage collection crashes with QMap.:
the garbage collection seems to crash the app due to the class A copy.
Neither standard C++ nor Qt's C++ API (QML is another story) has garbage collection. An object is destroyed either when an auto scoped instance goes out of scope, or when a dynamically allocated instance is deleted. You can determine when this is occurs via the destructor.
Thanks. You're correct. I miss-characterised the crash. When I call function B (with 'const') from another thread, Qmap[] seems to copy class A then the app crashes when trying to read stuff from inside the class A. I'm guessing since the copy goes out of scope. I don't fully understand why but the solution appears to be removing all the const qualifiers.
That said, I'll experiment more with Qmap::value(), although it's not clear from the documentation if it returns a copy or a const reference. Class A has some dynamically allocated internal stuff which complicates matters.
Thanks again.
@mjsmithers said in const function causes garbage collection crashes with QMap.:
experiment more with Qmap::value(), although it's not clear from the documentation if it returns a copy or a const reference.
As per my previous, I think this is 100% clear?