Zeiger auf Vector mit Iteratoren: Bei Zugriff Absturz



  • Hallo,

    ich versuche grad ein Code zu schreiben, der folgendes macht:
    Es sollen Linien gesucht werden, die sich in der Umgebung von anderen Linien befinden, und dann wieder Linien in deren Umgebung, also ist die Funktion rekursiv. So bekomme ich dann eine Gruppe von Linien, die ich als Iteratoren in einen Vektor schreibe, um diese Elemente (bis auf das erste) aus den Linienvektor zu löschen.

    Hier der Code:

    void parallel_lines(std::vector<std::vector<LineData>::iterator>*, std::vector<LineData>*);
    
    void CPreProcessing::parallel_lines(std::vector<std::vector<LineData>::iterator>* vec, std::vector<LineData>* HoughLines)
    {
        int j;
        int marker = 0;
        int i = HoughLines->size();
        std::cout<<"\n -->>> DELETE PARALLEL LINES, #Hough lines: "<<HoughLines->size()<<std::endl;
        for(i; i>=0; i--)
        {
            j = 0;
            std::vector<LineData>::iterator iter = (HoughLines[0]).begin();
            while(iter != (HoughLines[0]).end())
            {
                if (i != j)
                {
                    if((abs(((HoughLines[0])[i]).StartPt.x - ((HoughLines[0])[j]).StartPt.x) < 3
                        || abs(((HoughLines[0])[i]).EndPt.x - ((HoughLines[0])[j]).EndPt.x) < 3)
                        && abs(((HoughLines[0])[i]).d_slope - ((HoughLines[0])[j]).d_slope) < 1)
                    {
                        for(int m = 0; m < vec->size(); m++)
                        {
                            if(&*(vec->at(m)) == &*iter)
                            {
                                marker = 1;
                            }
                        }
                        if(marker == 0)
                        {
                            (*vec).push_back(iter);
                            parallel_lines(vec, HoughLines);
                        }
                    }
                    else
                      iter++;
                      j++;
                }
                else
                    iter++;
                    j++;
            }
            for(int m = 0; m < vec->size(); m++)
            {
                if (m != 0)
                {
                    (HoughLines)[0].erase((*vec)[m]);
                }
            }
        }
    };
    

    Sobald ich auf den Vektor vec zugreife, stürzt das Programm ab, also hier in diesem Fall bei size() in der for-Bedingung.
    Weiß jemand was ich da falsch mache? Compiliert wird ja alles...

    Danke



  • Hier mit C++-Tags:

    void CPreProcessing::parallel_lines(std::vector<std::vector<LineData>::iterator>* vec, std::vector<LineData>* HoughLines) 
    { 
        int j; 
        int marker = 0; 
        int i = HoughLines->size(); 
        std::cout<<"\n -->>> DELETE PARALLEL LINES, #Hough lines: "<<HoughLines->size()<<std::endl; 
        for(i; i>=0; i--) 
        { 
            j = 0; 
            std::vector<LineData>::iterator iter = (HoughLines[0]).begin(); 
            while(iter != (HoughLines[0]).end()) 
            { 
                if (i != j) 
                { 
                    if((abs(((HoughLines[0])[i]).StartPt.x - ((HoughLines[0])[j]).StartPt.x) < 3 
                        || abs(((HoughLines[0])[i]).EndPt.x - ((HoughLines[0])[j]).EndPt.x) < 3) 
                        && abs(((HoughLines[0])[i]).d_slope - ((HoughLines[0])[j]).d_slope) < 1) 
                    { 
                        for(int m = 0; m < vec->size(); m++) 
                        { 
                            if(&*(vec->at(m)) == &*iter) 
                            { 
                                marker = 1; 
                            } 
                        } 
                        if(marker == 0) 
                        { 
                            (*vec).push_back(iter); 
                            parallel_lines(vec, HoughLines); 
                        } 
                    } 
                    else 
                      iter++; 
                      j++; 
                } 
                else 
                    iter++; 
                    j++; 
            } 
            for(int m = 0; m < vec->size(); m++) 
            { 
                if (m != 0) 
                { 
                    (HoughLines)[0].erase((*vec)[m]); 
                } 
            } 
        } 
    };
    


  • Wo wird deine Funktion aufgerufen und wie sehen die Daten in vec aus. Du bist dir sicher dass vec kein Nullpointer ist?



  • Doch, war der 😃

    std::vector<std::vector<LineData>::iterator>* vec;
    parallel_lines(vec, HoughLines);
    

    Das ist der Aufruf, aber nun steht ja in vec nichts drin, und bei size erzählt der mir nun was von Millionen von Elementen und stürzt dann natürlich ab, wenn aufs erste zugegriffen wird 😕



  • Einen Zeiger auf einen Vektor von Iteratoren eines Vektors auf Zeilen? Bist Du sicher, dass Du da nicht ein bisschen übertrieben hast?



  • Mir fällt keine bessere Lösung ein, das erase will ja nunmal Iteratoren...
    Als int kann ich das ja deshalb nicht speichern, weil ich ja nachher alle Elemente aus dieser Gruppe, die der Vektor darstellt, löschen will, und der ja seine Iteratoren haben will...

    Wenn das so sonst gar nich klappt, müsste ich den sonst jede Linie von links nach rechts durchgehen lassen und dann ggf. die linke von der aktuellen löschen oder sowas



  • Björn87 schrieb:

    Doch, war der 😃

    std::vector<std::vector<LineData>::iterator>* vec;
    parallel_lines(vec, HoughLines);
    

    Das ist der Aufruf, aber nun steht ja in vec nichts drin, und bei size erzählt der mir nun was von Millionen von Elementen und stürzt dann natürlich ab, wenn aufs erste zugegriffen wird 😕

    Wenn das dein Aufruf ist, ist es klar... Du rufst die Funktion mit einem nicht initialisierten Zeiger auf, der irgendwo hin zeigt.

    Versuchs mal so

    std::vector<std::vector<LineData>::iterator> vec;
    parallel_lines(&vec, HoughLines);
    

    Wobei du hier auf die Lebensdauer von vec aufpassen musst...



  • Und selbst dann ist die Funktion immer noch absturzgefährdet, denn die Iteratoren können sich ja bei interner Neuallozierung des Vectors ändern (bei push_back).

    Hallo Björn87,

    nimm einfach den Index (size_t) anstatt des Iterators.
    Und bei erase(...) kannst du dann mittels "vec.begin() + index" den aktuell korrekten Iterator als Parameter angeben.

    Und mit Referenzen solltest du dich auch mal beschäftigen, dann könntest du nämlich auf die ganzen Zeiger und Dereferenzierungen verzichten 😉
    (HoughLines[0] sagt mir nämlich, daß du einiges an C++ noch nicht ganz verstanden hast)

    Zusammengefaßt also:

    void PreProcessing::parallel_lines(std::vector<size_t> &vec, std::vector<LineData> &HoughLines)
    {
      // ...
      vec.push_back(j);
      // ...
    
      HoughLines.erase(vec.begin()+m);
    }
    

    Und wenn du alle bis auf den ersten aus dem Vector löschen willst, dann geht auch einfach:

    HoughLines.erase(vec.begin()+1, vec.end());
    


  • Ok, danke, werde ich mal versuchen, über Ostern war ich leider nicht da.
    Das mit dem HoughLines[0] habe ich vom Code meines Betreuers übernommen, ehrlich gesagt, hab ich kein Plan was das [0] da sein soll 😃
    Das mit dem ersten Element löschen war jetzt nur ein Beispiel, das will ich später so ändern, dass er alle Linie bis auf die in der Mitte löscht, bloß dazu muss ich erstmal die mittlere Linie finden usw.

    Ich versuchs dann einfach mal so, danke


Anmelden zum Antworten