# 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 ersteres

bei folgendem Code (viel kürzer ging nicht) kommen seltsame Sachen raus...

``````#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 habe

Ansonsten 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.
-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
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
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
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