Wann wird iterator hier ungültig? [gelöst]
-
Hallo allerseits,
ich glaube ich habe iteratoren nicht verstanden oder mein g++-8 hat Fehler...
Üblicherweise ist es ersteresbei folgendem Code (viel kürzer ging nicht) kommen seltsame Sachen raus...
https://wandbox.org/permlink/COHxvkIs43rih0qf
#include <iostream> #include <vector> #include <algorithm> #include <random> //#include <QPointF> // im Original wird Dot von QPointF abgeleitet struct Point { float _x, _y; auto x() const { return _x;} auto y() const { return _y;} }; struct Dot : public Point /*QPointF*/ { float found = -1; friend std::ostream& operator<<(std::ostream& os, const Dot& d) { return os << d.x() << "; " << d.y() << " : " << d.found; } }; template <class Iterator> extern std::size_t wrap_my(Iterator b, Iterator e) { auto size = std::distance(b, e); if (size < 4) return size; auto mmx = std::minmax_element(b, e, [] (const Dot &a, const Dot &b) { return a.x() == b.x() ? a.y() < b.y() : a.x() < b.x(); }); mmx.second->found = 1; mmx.first->found = 3; std::cerr << __func__ << "(): minx:" << mmx.first->x() << " found: " << mmx.first->found << " maxx:" << mmx.second->x() << " found: " << mmx.second->found << "\n"; auto mmy = std::minmax_element(b, e, [] (const Dot &a, const Dot &b) { return a.y() == b.y() ? a.x() < b.x() : a.y() < b.y(); }); mmy.first->found = 0; mmy.second->found = 2; std::cerr << __func__ << "(): minx:" << mmx.first->x() << " found: " << mmx.first->found << " maxx:" << mmx.second->x() << " found: " << mmx.second->found << "\n"; std::cerr << __func__ << "(): miny:" << mmy.first->y() << " found: " << mmy.first->found << " maxy:" << mmy.second->y() << " found: " << mmy.second->found << "\n"; return 4; } int main(int /*argc*/, char **/*argv*/) { // Testdaten: std::random_device rd; std::mt19937 gen(rd()); std::vector<double> i{20, 50, 100, 200, 300}; std::vector<double> w{0, .1, 1, .1, 0}; std::piecewise_linear_distribution<float> dis(i.begin(), i.end(), w.begin()); std::vector<Dot> dots; for (std::size_t i=0; i<7; ++i) { dots.emplace_back(Dot{{dis(gen), dis(gen)}, -1}); std::cerr << i << " = " << dots.back() << "\n"; } // Test: wrap_my(dots.begin(), dots.end()); return EXIT_SUCCESS; }
Ausgabe (3 Beispiele):
0 = 175.756; 159.998 : -1 1 = 130.504; 109.756 : -1 2 = 126.563; 197.901 : -1 3 = 196.538; 124.723 : -1 4 = 153.585; 128.313 : -1 5 = 101.961; 92.0283 : -1 6 = 134.675; 92.7217 : -1 wrap_my(): minx:101.961 found: 3 maxx:196.538 found: 1 wrap_my(): minx:101.961 found: 0 maxx:196.538 found: 1 wrap_my(): miny:92.0283 found: 0 maxy:197.901 found: 2 [...] wrap_my(): minx:67.2401 found: 3 maxx:236.327 found: 1 wrap_my(): minx:67.2401 found: 2 maxx:236.327 found: 1 wrap_my(): miny:102.391 found: 0 maxy:285.935 found: 2 [... Hier mal richtig:] wrap_my(): minx:59.7193 found: 3 maxx:236.601 found: 1 wrap_my(): minx:59.7193 found: 3 maxx:236.601 found: 1 wrap_my(): miny:62.4498 found: 0 maxy:166.222 found: 2
Die Dot.found-Ausgaben sind doch etwas wirr... Allerdings stimmt es manchmal...
Richtig ist die erste Zeile von wrap_my (minx, maxx), die 2. sollte nochmal
zum testen gleich der ersten sein. Die dritte für miny,maxy ist wieder korrekt.Werden die Iteratoren so schnell ungültig? Es werden zwischen den Ausgaben
ja keine Elemente dem vector hinzugefügt oder welche geswappt...Leider habe ich wohl im Zustand geistiger Umnachtung vor ein paar Tagen den
g++-7 gegen den g++-8 ausgetauscht. Dachte es gibt da eine stable-Version.
War wohl nix wie ich *danach* auf der GCC-Homepage gesehen habeAnsonsten hab ich noch den kaputten 4.8 (Danke suse, Danke Novell!).
Der will aber nicht mit c++17 oder c++1z...Compiliert wurde mit:
g++-8 -c -pipe -pedantic -Wall -Wpedantic -Wextra -g -DDEBUG -std=c++17 -Wall -W -D_REENTRANT -fPIC -DQT_DEPRECATED_WARNINGS -DQT_QML_DEBUG -I../../iterator_test -I. -I/home/balu_home/dirk/develop/qt-downloads/5.10.1/gcc_64/mkspecs/linux-g++ -o main.o ../main.cpp g++-8 -o iterator_test main.o -lpthread
Compiler-Version und libstdc++:
Using built-in specs. COLLECT_GCC=g++-8 COLLECT_LTO_WRAPPER=/usr/lib64/gcc/x86_64-suse-linux/8/lto-wrapper OFFLOAD_TARGET_NAMES=hsa:nvptx-none Target: x86_64-suse-linux Configured with: ../configure --prefix=/usr --infodir=/usr/share/info --mandir=/usr/share/man --libdir=/usr/lib64 --libexecdir=/usr/lib64 --enable-languages=c,c++,objc,fortran,obj-c++,ada,go --enable-offload-targets=hsa,nvptx-none=/usr/nvptx-none, --without-cuda-driver --disable-werror --with-gxx-include-dir=/usr/include/c++/8 --enable-ssp --disable-libssp --disable-libvtv --disable-cet --disable-libcc1 --disable-plugin --with-bugurl=http://bugs.opensuse.org/ --with-pkgversion='SUSE Linux' --with-slibdir=/lib64 --with-system-zlib --enable-__cxa_atexit --enable-libstdcxx-allocator=new --disable-libstdcxx-pch --with-default-libstdcxx-abi=gcc4-compatible --enable-version-specific-runtime-libs --with-gcc-major-version-only --enable-linker-build-id --enable-linux-futex --enable-gnu-indirect-function --program-suffix=-8 --without-system-libunwind --enable-multilib --with-arch-32=x86-64 --with-tune=generic --build=x86_64-suse-linux --host=x86_64-suse-linux Thread model: posix gcc version 8.0.1 20180226 (experimental) [trunk revision 257983] (SUSE Linux) Name : libstdc++6-gcc8 Version : 8.0.1+r257983 Release : 3.1 Architecture: x86_64 Install Date: So 04 Mär 2018 07:54:35 CET Group : System/Libraries Size : 1602616 License : GPL-3.0-with-GCC-exception Signature : DSA/SHA1, Do 01 Mär 2018 18:36:41 CET, Key ID 927f5cc86300dadb Source RPM : gcc8-8.0.1+r257983-3.1.src.rpm Build Date : Do 01 Mär 2018 18:13:16 CET Build Host : build73 Relocations : (not relocatable) Vendor : obs://build.opensuse.org/devel:gcc URL : http://gcc.gnu.org/ Summary : The standard C++ shared library Description : The standard C++ library, needed for dynamically linked C++ programs. Distribution: devel:gcc / openSUSE_Leap_42.3
So, mehr infos geht nicht...
Grüße!
Edit: Link auf Wandbox-Onlinecompiler hinzugefügt...
-
dirkski schrieb:
die 2. sollte nochmal zum testen gleich der ersten sein.
Nur dann, wenn nicht derselbe Punkt Min oder Max für X und Y ist.
-
MFK schrieb:
dirkski schrieb:
die 2. sollte nochmal zum testen gleich der ersten sein.
Nur dann, wenn nicht derselbe Punkt Min oder Max für X und Y ist.
Danke, ich Blindfisch