summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/doc/snippets/code/doc_src_containers.cpp30
-rw-r--r--src/corelib/doc/src/containers.qdoc14
-rw-r--r--src/corelib/doc/src/implicit-sharing.qdoc20
-rw-r--r--src/corelib/tools/qhash.cpp10
-rw-r--r--src/corelib/tools/qlinkedlist.cpp14
-rw-r--r--src/corelib/tools/qlist.cpp10
-rw-r--r--src/corelib/tools/qmap.cpp10
-rw-r--r--src/corelib/tools/qset.qdoc14
-rw-r--r--src/corelib/tools/qvector.cpp10
9 files changed, 114 insertions, 18 deletions
diff --git a/src/corelib/doc/snippets/code/doc_src_containers.cpp b/src/corelib/doc/snippets/code/doc_src_containers.cpp
index 350b2a91f2..6e59a8a548 100644
--- a/src/corelib/doc/snippets/code/doc_src_containers.cpp
+++ b/src/corelib/doc/snippets/code/doc_src_containers.cpp
@@ -273,3 +273,33 @@ QString onlyLetters(const QString &in)
return out;
}
//! [23]
+
+//! [24]
+QVector<int> a, b;
+a.resize(100000); // make a big vector filled with 0.
+
+QVector<int>::iterator i = a.begin();
+// WRONG way of using the iterator i:
+b = a;
+/*
+ Now we should be careful with iterator i since it will point to shared data
+ If we do *i = 4 then we would change the shared instance (both vectors)
+ The behavior differs from STL containers. Avoid doing such things in Qt.
+*/
+
+a[0] = 5;
+/*
+ Container a is now detached from the shared data,
+ and even though i was an iterator from the container a, it now works as an iterator in b.
+ Here the situation is that (*i) == 0.
+*/
+
+b.clear(); // Now the iterator i is completely invalid.
+
+int j = *i; // Undefined behavior!
+/*
+ The data from b (which i pointed to) is gone.
+ This would be well-defined with STL containers (and (*i) == 5),
+ but with QVector this is likely to crash.
+*/
+//! [24]
diff --git a/src/corelib/doc/src/containers.qdoc b/src/corelib/doc/src/containers.qdoc
index ff2df9c020..fa26409d83 100644
--- a/src/corelib/doc/src/containers.qdoc
+++ b/src/corelib/doc/src/containers.qdoc
@@ -533,10 +533,18 @@
This problem doesn't occur with functions that return a const or
non-const reference to a container.
+ \section3 Implicit sharing iterator problem
+
\l{Implicit sharing} has another consequence on STL-style
- iterators: You must not take a copy of a container while
- non-const iterators are active on that container. Java-style
- iterators don't suffer from that limitation.
+ iterators: you should avoid copying a container while
+ iterators are active on that container. The iterators
+ point to an internal structure, and if you copy a container
+ you should be very careful with your iterators. E.g:
+
+ \snippet code/doc_src_containers.cpp 24
+
+ The above example only shows a problem with QVector, but
+ the problem exists for all the implicitly shared Qt containers.
\keyword foreach
\section1 The foreach Keyword
diff --git a/src/corelib/doc/src/implicit-sharing.qdoc b/src/corelib/doc/src/implicit-sharing.qdoc
index 814f8140f3..1185fe8348 100644
--- a/src/corelib/doc/src/implicit-sharing.qdoc
+++ b/src/corelib/doc/src/implicit-sharing.qdoc
@@ -89,9 +89,12 @@
of data. Objects can easily be assigned, sent as function arguments,
and returned from functions.
- Implicit sharing takes place behind the scenes; the programmer
- does not need to worry about it. Even in multithreaded
- applications, implicit sharing takes place, as explained in
+ Implicit sharing mostly takes place behind the scenes;
+ the programmer rarely needs to worry about it. However, Qt's
+ container iterators have different behavior than those from
+ the STL. Read \l{Implicit sharing iterator problem}.
+
+ In multithreaded applications, implicit sharing takes place, as explained in
\l{Thread-Support in Qt Modules#Threads and Implicitly Shared Classes}
{Threads and Implicitly Shared Classes}.
@@ -105,9 +108,10 @@
greater than one. (This is often called \e {copy-on-write} or
\e {value semantics}.)
- An implicitly shared class has total control of its internal data. In
+ An implicitly shared class has control of its internal data. In
any member functions that modify its data, it automatically detaches
- before modifying the data.
+ before modifying the data. Notice, however, the special case with
+ container iterators; see \l{Implicit sharing iterator problem}.
The QPen class, which uses implicit sharing, detaches from the shared
data in all member functions that change the internal data.
@@ -133,9 +137,9 @@
In this example, \c p1 and \c p2 share data until QPainter::begin()
is called for \c p2, because painting a pixmap will modify it.
- \warning Do not copy an implicitly shared container (QMap,
- QVector, etc.) while you are iterating over it using an non-const
- \l{STL-style iterators}{STL-style iterator}.
+ \warning Be careful with copying an implicitly shared container
+ (QMap, QVector, etc.) while you use
+ \l{STL-style iterators}{STL-style iterator}. See \l{Implicit sharing iterator problem}.
\keyword implicitly shared classes
\annotatedlist shared
diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp
index 7f6feaf8a0..f14fac00b8 100644
--- a/src/corelib/tools/qhash.cpp
+++ b/src/corelib/tools/qhash.cpp
@@ -1594,6 +1594,11 @@ void QHashData::checkSanity()
need to keep iterators over a long period of time, we recommend
that you use QMap rather than QHash.
+ \warning Iterators on implicitly shared containers do not work
+ exactly like STL-iterators. You should avoid copying a container
+ while iterators are active on that container. For more information,
+ read \l{Implicit sharing iterator problem}.
+
\sa QHash::const_iterator, QMutableHashIterator
*/
@@ -1791,6 +1796,11 @@ void QHashData::checkSanity()
internal data structure. If you need to keep iterators over a long
period of time, we recommend that you use QMap rather than QHash.
+ \warning Iterators on implicitly shared containers do not work
+ exactly like STL-iterators. You should avoid copying a container
+ while iterators are active on that container. For more information,
+ read \l{Implicit sharing iterator problem}.
+
\sa QHash::iterator, QHashIterator
*/
diff --git a/src/corelib/tools/qlinkedlist.cpp b/src/corelib/tools/qlinkedlist.cpp
index 28319f3fda..e967163b8b 100644
--- a/src/corelib/tools/qlinkedlist.cpp
+++ b/src/corelib/tools/qlinkedlist.cpp
@@ -691,9 +691,12 @@ const QLinkedListData QLinkedListData::shared_null = {
Multiple iterators can be used on the same list. If you add items
to the list, existing iterators will remain valid. If you remove
items from the list, iterators that point to the removed items
- will become dangling iterators. However, because of how \l{implicit
- sharing} works, you must not take a copy of a container while
- iterators are active on that container.
+ will become dangling iterators.
+
+ \warning Iterators on implicitly shared containers do not work
+ exactly like STL-iterators. You should avoid copying a container
+ while iterators are active on that container. For more information,
+ read \l{Implicit sharing iterator problem}.
\sa QLinkedList::const_iterator, QMutableLinkedListIterator
*/
@@ -910,6 +913,11 @@ const QLinkedListData QLinkedListData::shared_null = {
items from the list, iterators that point to the removed items
will become dangling iterators.
+ \warning Iterators on implicitly shared containers do not work
+ exactly like STL-iterators. You should avoid copying a container
+ while iterators are active on that container. For more information,
+ read \l{Implicit sharing iterator problem}.
+
\sa QLinkedList::iterator, QLinkedListIterator
*/
diff --git a/src/corelib/tools/qlist.cpp b/src/corelib/tools/qlist.cpp
index d8ccf2cc43..0811c3793e 100644
--- a/src/corelib/tools/qlist.cpp
+++ b/src/corelib/tools/qlist.cpp
@@ -1292,6 +1292,11 @@ void **QListData::erase(void **xi)
iterators over a long period of time, we recommend that you use
QLinkedList rather than QList.
+ \warning Iterators on implicitly shared containers do not work
+ exactly like STL-iterators. You should avoid copying a container
+ while iterators are active on that container. For more information,
+ read \l{Implicit sharing iterator problem}.
+
\sa QList::const_iterator, QMutableListIterator
*/
@@ -1542,6 +1547,11 @@ void **QListData::erase(void **xi)
iterators over a long period of time, we recommend that you use
QLinkedList rather than QList.
+ \warning Iterators on implicitly shared containers do not work
+ exactly like STL-iterators. You should avoid copying a container
+ while iterators are active on that container. For more information,
+ read \l{Implicit sharing iterator problem}.
+
\sa QList::iterator, QListIterator
*/
diff --git a/src/corelib/tools/qmap.cpp b/src/corelib/tools/qmap.cpp
index ab9b1d23ab..4da9669a39 100644
--- a/src/corelib/tools/qmap.cpp
+++ b/src/corelib/tools/qmap.cpp
@@ -1215,6 +1215,11 @@ void QMapDataBase::freeData(QMapDataBase *d)
items from the map, iterators that point to the removed items
will become dangling iterators.
+ \warning Iterators on implicitly shared containers do not work
+ exactly like STL-iterators. You should avoid copying a container
+ while iterators are active on that container. For more information,
+ read \l{Implicit sharing iterator problem}.
+
\sa QMap::const_iterator, QMutableMapIterator
*/
@@ -1433,6 +1438,11 @@ void QMapDataBase::freeData(QMapDataBase *d)
items from the map, iterators that point to the removed items
will become dangling iterators.
+ \warning Iterators on implicitly shared containers do not work
+ exactly like STL-iterators. You should avoid copying a container
+ while iterators are active on that container. For more information,
+ read \l{Implicit sharing iterator problem}.
+
\sa QMap::iterator, QMapIterator
*/
diff --git a/src/corelib/tools/qset.qdoc b/src/corelib/tools/qset.qdoc
index a0bc206014..e66a59a09c 100644
--- a/src/corelib/tools/qset.qdoc
+++ b/src/corelib/tools/qset.qdoc
@@ -643,8 +643,12 @@
\snippet code/doc_src_qset.cpp 10
- Multiple iterators can be used on the same set. However, you may
- not attempt to modify the container while iterating on it.
+ Multiple iterators can be used on the same set.
+
+ \warning Iterators on implicitly shared containers do not work
+ exactly like STL-iterators. You should avoid copying a container
+ while iterators are active on that container. For more information,
+ read \l{Implicit sharing iterator problem}.
\sa QSet::const_iterator, QMutableSetIterator
*/
@@ -682,8 +686,10 @@
\snippet code/doc_src_qset.cpp 12
- Multiple iterators can be used on the same set. However, you may
- not attempt to modify the container while iterating on it.
+ \warning Iterators on implicitly shared containers do not work
+ exactly like STL-iterators. You should avoid copying a container
+ while iterators are active on that container. For more information,
+ read \l{Implicit sharing iterator problem}.
\sa QSet::iterator, QSetIterator
*/
diff --git a/src/corelib/tools/qvector.cpp b/src/corelib/tools/qvector.cpp
index 11990d30b2..b9281c6915 100644
--- a/src/corelib/tools/qvector.cpp
+++ b/src/corelib/tools/qvector.cpp
@@ -957,6 +957,11 @@
iterators}. The STL-style non-const iterator is simply a typedef
for "T *" (pointer to T).
+ \warning Iterators on implicitly shared containers do not work
+ exactly like STL-iterators. You should avoid copying a container
+ while iterators are active on that container. For more information,
+ read \l{Implicit sharing iterator problem}.
+
\sa QVector::begin(), QVector::end(), QVector::const_iterator, QMutableVectorIterator
*/
@@ -969,6 +974,11 @@
iterators}. The STL-style const iterator is simply a typedef for
"const T *" (pointer to const T).
+ \warning Iterators on implicitly shared containers do not work
+ exactly like STL-iterators. You should avoid copying a container
+ while iterators are active on that container. For more information,
+ read \l{Implicit sharing iterator problem}.
+
\sa QVector::constBegin(), QVector::constEnd(), QVector::iterator, QVectorIterator
*/