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

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


Log in to reply