void value not ignored as it should be
-
Das pop() void als Rückgabewert hat, liegt daran, dass es das Objekt als Kopie zurückgeben muss (weil das eigentliche Objekt zerstört wird). Wenn man nun große Objekte verwaltet und einfach nur das oberste Element löschen will, ohne dieses dann noch weiter zu verwenden, wäre das sehr ineffizient.
-
Jetzt habe ich ein neues Problem. Vielleicht sollte ich mal kurz sagen was ich hier eigentlich tue!

Also ich schreibe ein Programm das automatisch rote Augen in einem Bild finden soll und diese auf Wunsch auch automatisch korrigiert.
Dazu nutze ich CImg, um die Pixeloperationen durchzuführen.
Der vorhin gezeigte Ausschnitt aus dem Algorithmus ist der "Connected Components Labeling"-Abschnitt, hier wird das binarisierte Bild in verschiedene Objekte zerlegt.
Bei einem Bild der Größe 800x600 funktioniert das auch alles noch, aber bei größeren Bildern bricht das Programm mit einem "Segmentation Fault" ab. Nun weiß ich nicht warum. Ich denke es liegt am Stack, denn wenn ich nicht mehr auf den Stack pushe dann bricht es auch nicht ab.
Hat ein Stack eine Begrenzung?Hier mal der Code, der abbricht:
CImg<imgType> EyeLocatorPriv::labelImage() { CImg<imgType> labels(width,height,1,1); labels.fill(0); stack<Position*> st; Position* pos = 0; int lab = 1; for (int x=1; x<width-1;x++) { for (int y=1; y<height-1; y++) { if (redBinaryMask(x,y) == 0) continue; if (labels(x,y) > 0) continue; // push the position on the stack and assign label st.push(new Position(x,y)); labels(x,y) = lab; while (!st.empty()) { pos = st.top(); st.pop(); int i = pos->x; int j = pos->y; if (redBinaryMask(i-1,j-1) == 255 && labels(i-1,j-1) == 0) { st.push(new Position(i-1,j-1)); labels(i-1,j-1) = lab; } if (redBinaryMask(i-1,j) == 255 && labels(i-1,j) == 0) { st.push(new Position(i-1,j)); labels(i-1,j) = lab; } if (redBinaryMask(i-1,j+1) == 255 && labels(i-1,j+1) == 0) { st.push(new Position(i-1,j+1)); labels(i-1,j+1) = lab; } if (redBinaryMask(i,j-1) == 255 && labels(i,j-1) == 0) { st.push(new Position(i,j-1)); labels(i,j-1) = lab; } if (redBinaryMask(i,j+1) == 255 && labels(i,j+1) == 0) { st.push(new Position(i,j+1)); labels(i,j+1) = lab; } if (redBinaryMask(i+1,j-1) == 255 && labels(i+1,j-1) == 0) { st.push(new Position(i+1,j-1)); labels(i+1,j-1) = lab; } if (redBinaryMask(i+1,j) == 255 && labels(i+1,j) == 0) { st.push(new Position(i+1,j)); labels(i+1,j) = lab; } if (redBinaryMask(i+1,j+1) == 255 && labels(i+1,j+1) == 0) { st.push(new Position(i+1,j+1)); labels(i+1,j+1) = lab; } } // end while lab++; } } components = lab; return labels; }Was kann denn das sein? Läuft der Stack einfach voll? Das wäre aber doof weil normalerweise sind meine digitalen Fotos alle so 3008x2272px groß...
Jemand eine Idee?
-
Laut einem meiner Bücher soll man in STL-Containern keine Zeiger, sondern normale Objekte abspeichern, da die Container intern Objekte verschieben, kopieren, usw. und es deswegen zu Fehlern kommen kann. Probier doch mal den Algorithmus mit stack<Position> (ohne Zeiger). Vielleicht löst das dein Problem. Außerdem ersparst du dir dann das explizite Freigeben der Zeiger.
-
XMaster schrieb:
Laut einem meiner Bücher soll man in STL-Containern keine Zeiger, sondern normale Objekte abspeichern, da die Container intern Objekte verschieben, kopieren, usw. und es deswegen zu Fehlern kommen kann.
Das wundert mich nu ein wenig. Wenn man Container mit Zeigern benutzt, werdne ja nur die Zeiger verschoben udn kopiert, was eigentlich kein Problem sein sollte. Die Objekte die dahinter stecken, bleiben ja unberuehrt.
Ausserdem, wenn Container mit Zeigern pfui sind, wie soll man dann folgendes behandeln:
- Sammlungen von abgeleiteten Objekten der selben Basisklasse (Stichwort Polymorphie)
- Sammlungen von nicht-kopierbaren ObjektenIn beiden Faellen erscheinen mir Container mit Zeigern als die natuerliche Loesung, vorausgesetzt man schafft keine Speicherlecks...
-
XMaster schrieb:
Laut einem meiner Bücher soll man in STL-Containern keine Zeiger, sondern normale Objekte abspeichern, ...
Das hast Du vermutlich mißverstanden. Ich denke mal, dass dort geraten wird, "... keine Zeiger auf Objekte im Container anzulegen ..."
Das hat im Deutschen eine fiese Doppeldeutigkeit: Ich klammere mal:
"... keine (Zeiger auf Objekte) im Container anzulegen ..." (= etwas im Container ablegen)
"... keine Zeiger auf (Objekte im Container) anzulegen ..." (= Zeiger auf etwas anzulegen)Vergleich:
A) "... (Zeiger auf Objekte) im Container ..."vector<myType*> vec(2); // Vector von Zeigern auf myType // x &x vec[1] &vec[1] // -------------------------------- myType x('S'); // 'S' 0x1234 0x0000 0xaffe vec[1] = &x; // 'S' 0x1234 0x1234 0xaffe vec.resize(2000); // 'S' 0x1234 0x1234 0xdead // => selbst wenn die Zeiger in vec verlagert werden, behalten sie doch dieselben Wert // => sie zeigen weiterhin dahin, wo sie sollen // => OK
"... Zeiger auf (Objekte im Container) ..."vector<myType> vec(2); // Vector von myType-Objekten // x &x vec[1] &vec[1] p // ------------------------------------- myType x('S'); // 'S' 0x1234 0 0xaffe - vec[1] = x; // 'S' 0x1234 'S' 0xaffe - myType* p = &vec[1]; // 'S' 0x1234 'S' 0xaffe 0xaffe vec.resize(2000); // 'S' 0x1234 'S' 0xdead 0xaffe // => Nach der Verlagerung hat zwar vec[1] noch denselben Wert (Kopiert von x) aber eine andere Adresse // => p zeigt weiterhin auf 0xaffe, aber vec[1] liegt inzwischen auf 0xdead // => DANGER !!!Gruß,
Simon2.
-
XMaster schrieb:
Laut einem meiner Bücher soll man in STL-Containern keine Zeiger, sondern normale Objekte abspeichern, da die Container intern Objekte verschieben, kopieren, usw. und es deswegen zu Fehlern kommen kann. Probier doch mal den Algorithmus mit stack<Position> (ohne Zeiger). Vielleicht löst das dein Problem. Außerdem ersparst du dir dann das explizite Freigeben der Zeiger.
Mal abgesehen von der expliziten Freigabe ist diese Aussage humbug (in welchem Buch steht die?). Container von Zeigern sind aus den von pumuckl genannten Gründen durchaus gängig.
Eine Alternative wären die pointer container in boost, welche sich selbst um die Freigabe der Zeiger kümmern, oder das speichern von boost smart pointern in einem Standardcontainer.
-
Wenn ich keine Zeiger nutze, kann ich doch auch keine Objekte dynamisch anlegen (das muss ich aber)...
Meint ihr ich sollte mal boost installieren und die dortigen Container einsetzen?
-
TheGrudge schrieb:
Wenn ich keine Zeiger nutze,...
Lies nochmal !
Deine Prämisse bezieht sich hier auf eine These, der schon massiv widersprochen wurde.Gruß,
Simon2.
-
Simon2 schrieb:
Phoemuex schrieb:
Ist nicht intuitiv, aber nötig, um das ganze Threadsafe zu machen. Wenn pop den Wert zurückgibt, gibt es KEINE Möglichkeit, das komplett Threadsafe zu realisieren.
Felix
hmmm ... ist Threadsafe wirklich das Kriterium ? Ich hätte eher an Exceptionsafe gedacht ....
Gruß,
Simon2.
Du hast natürlich recht
Gut, wenn man immer jemanden hat, der einen korrigiert 
Felix
-
Ja schon klar das dies wohl nix damit zu tun hat, ich wollte ja nur erklären warum ich Zeiger nutze. Trotzdem löst das nicht mein Problem, ich verstehe einfach nicht wieso ich einen Segmentation Fault bekomme.
-
Phoemuex schrieb:
...
Du hast natürlich recht
Gut, wenn man immer jemanden hat, der einen korrigiert 
Felix
Gut ! Ich hatte schon einen Knoten im Gehirn, weil ich dachte, ich wäre zu blöd.
Danke für die Rückmeldung,

Simon2.
-
Ok ich habe nun raus gefunden, das es wohl nicht an der Bildergröße liegt (also kein Speicherüberlauf), denn es gehen auch manche Bilder nicht, die nur 300x240px groß sind (oder andere Dimensionen).
Was kann denn das verursachen? Irgendwie ist die Fehlermeldung "Segmentation Fault" wirklich nicht sehr aussagekräftig... Wie könnte ich denn das debuggen? Ich komme normal von Python her und ich weiß nun nicht wie ich da rangehen soll... bei Python bekommt man eigentlich immer aussagekräftige Exceptions.
-
OK ich habe mittlerweile mit GDB raus gefunden, das es wohl Zugriffsprobleme gibt bei manchen Bildern, warum weiß ich aber nicht.
Nun habe ich mal Valgrind installiert, aber ich habe nicht wirklich den Plan was ich damit machen kann.
Immerhin startet nun das Programm wenn es mit valgrind aufgerufen wird, aber das ist ja keine Lösung
Hier mal die Ausgabe: http://rafb.net/p/MH74yY52.html
Ich hoffe ihr könnt damit was anfangen, wie gesagt ich bin Python verwöhnt und dort gibt es ja Garbage Collectors, vielleicht ist das ja mein Problem...
-
OK ich habe noch einmal GDB benutzt und ich glaube ich weiß was passiert, ich greife wohl auf Indizes zu, die es nicht gibt.
Ich verstehe nur nicht wieso es passiert, denn es klappt bei manchen Bildern.Vielleicht findet ihr den Fehler... aber nichts desto trotz scheint valgrind mir massive Speicherprobleme zu zeigen, die ich wohl durch schlechte Pointerverwaltung hin bekomme

Ich poste nochmal den Code der diese Probleme verursacht:
CImg<imgType> EyeLocatorPriv::labelImage() { CImg<imgType> labels(width,height,1,1); labels.fill(0); stack<Position*> st; Position* pos = 0; int lab = 1; labelValues.clear(); for (int y=1; y<height-1; y++) { for (int x=1; x<width-1;x++) { if (redBinaryMask(x,y) == 0) continue; if (labels(x,y) > 0) continue; // push the position on the stack and assign label st.push(new Position(x,y)); labels(x,y) = lab; setLabelValue(lab); while (!st.empty()) { pos = st.top(); st.pop(); int i = pos->x; int j = pos->y; if ((redBinaryMask(i-1,j-1) == 255) && (labels(i-1,j-1) == 0)) { st.push(new Position(i-1,j-1)); labels(i-1,j-1) = lab; setLabelValue(lab); } if ((redBinaryMask(i-1,j) == 255) && (labels(i-1,j) == 0)) { st.push(new Position(i-1,j)); labels(i-1,j) = lab; setLabelValue(lab); } if ((redBinaryMask(i-1,j+1) == 255) && (labels(i-1,j+1) == 0)) { st.push(new Position(i-1,j+1)); labels(i-1,j+1) = lab; setLabelValue(lab); } if ((redBinaryMask(i,j-1) == 255) && (labels(i,j-1) == 0)) { st.push(new Position(i,j-1)); labels(i,j-1) = lab; setLabelValue(lab); } if ((redBinaryMask(i,j+1) == 255) && (labels(i,j+1) == 0)) { st.push(new Position(i,j+1)); labels(i,j+1) = lab; setLabelValue(lab); } if ((redBinaryMask(i+1,j-1) == 255) && (labels(i+1,j-1) == 0)) { st.push(new Position(i+1,j-1)); labels(i+1,j-1) = lab; setLabelValue(lab); } if ((redBinaryMask(i+1,j) == 255) && (labels(i+1,j) == 0)) { st.push(new Position(i+1,j)); labels(i+1,j) = lab; setLabelValue(lab); } if ((redBinaryMask(i+1,j+1) == 255) && (labels(i+1,j+1) == 0)) { st.push(new Position(i+1,j+1)); labels(i+1,j+1) = lab; setLabelValue(lab); } } // end while lab++; } } // remove components with less than 25 pixels for (map<int,int>::iterator it = labelValues.begin(); it != labelValues.end();) { if (it->second <= 25) labelValues.erase(it++); else ++it; } // update labels cimg_forXY(labels,x,y) { if (labelValues.find(labels(x,y)) == labelValues.end()) labels(x,y) = 0; } return labels; }Irgendwas scheint wohl schief zu laufen beim pushen auf den Stack, denn die for-Schleifen können definitiv nicht über das Ziel hinaus schießen...