Unterschiedliche Ergebnisse Debug <-> Release
-
Hallo Freunde,
ich schreibe derzeit an einem Programm zur Mustererkennung innerhalb von digitalisierten Messdaten. Dabei werte ich anhand von allerlei Kennwerten den in einzelne Signalmuster unterteilten Signalverlauf aus und vergleiche mit den Kennwerten von vorgegebenen Referenzmustern. Ich hantiere dabei mit einer vielzahl von Containern und habe die Vermutung, dass ich bei der Auswertung bei einer Liste über eine Grenze hinauslaufe. Dabei bekomme ich beim Compilieren weder im Debug- noch im Release-Modus eine Warnung, geschweige denn einen Fehler angezeigt.
Das alleine wäre nicht das Problem, wenn ich nicht Unterschiede in den Auswertungsergebnissen zwischen den beiden Modi entdeckt hätte.Gibt es eine Möglichkeit, die Positionen leicht zu finden, an denen die Grenzen überschritten werden? Die Suche zieht sich inzwischen schon einige Tage hin und ist bisher nicht gerade erfolgreich gewesen :-(.
Habt Dank!
Gruß,
Holger
-
edward schrieb:
Gibt es eine Möglichkeit, die Positionen leicht zu finden, an denen die Grenzen überschritten werden? Die Suche zieht sich inzwischen schon einige Tage hin und ist bisher nicht gerade erfolgreich gewesen :-(.
die container umschreiben, daß sie im op[] ein assert haben.
wenn allerdings die zugriffe über iteratoren laufen, isses nicht so einfach, eher gesagt sogar recht schwierig.
-
volkard schrieb:
die container umschreiben, daß sie im op[] ein assert haben.
Meinst Du damit, den []-Operator zu überladen und mit ´nem ASSERT zu versehen? Tja, das wäre tatsächlich eine Möglichkeit... Aber leider hast Du recht, einige Zugriffe laufen über Iteratoren...
Gruß,
Holger
-
edward schrieb:
volkard schrieb:
die container umschreiben, daß sie im op[] ein assert haben.
Meinst Du damit, den []-Operator zu überladen und mit ´nem ASSERT zu versehen? Tja, das wäre tatsächlich eine Möglichkeit... Aber leider hast Du recht, einige Zugriffe laufen über Iteratoren...
Gruß,
Holgerum genau zu sein, sollte man ausschließlich mit containern arbeiten, die einen op[] haben, der assert drinne hat. naja, man arbeitet viel mit std::vector. egal, dem fummelt man ein nettes assert rein auf der eigenen maschine.
beim op[] ist es einfach.
beim iterator muß wohl normalerweider der iterator im debug-modus zusätzlich einen zeiger auf den container haben, um prüfen zu können. das wird zu schlimm.
ich wünsche dir erstmal glück, daß es beim op[] passiert ist.
die verwendeten op[] zu verfrickeln ist sicherlich noch schneller als ne klassische fehlersuche.
bei den iteratoren ist es gemeiner. dort hand anzulegen bei den standard-containern ist nicht lustig. eher unlustig. ich würde fast sagen, sogar demotivierend. und vermutlich im aufwand zu groß.
man könnte ganz unten tricksen und den globalen op new überladen und er ruft nur malloc auf und legt viel (viel viel, damit die schutzbereich vermutlich sich nicht überschneiden) mehr speicher an als nötig und macht am anfang und am ende einen mit 0xafafafaf belegten schutzbereich an und der überladenen globale op delete testet, ob der schutzbereich verletzt wurde und asserted. dann haste wenigstens den container, der dran schuld ist, aber noch nicht die code-zeile.
ist auch in ner viertel stunde schaffbar.
wenn das auch nicht hilft, mach ich dir den fehler für 100Eu/h weg. *g*
-
volkard schrieb:
um genau zu sein, sollte man ausschließlich mit containern arbeiten, die einen op[] haben, der assert drinne hat. naja, man arbeitet viel mit std::vector. egal, dem fummelt man ein nettes assert rein auf der eigenen maschine.
Ja, Du hast ja recht... Tschuldigung...
die verwendeten op[] zu verfrickeln ist sicherlich noch schneller als ne klassische fehlersuche.
Aus diesem Grund werde ich es auch erstmal damit versuchen...
Der Aufwand, einen Schutzbereich anzulegen, scheint mir nicht angemessen. Zumal ich schon genug Speicher alleine mit den Messdaten belege, die mit bis zu 2 Mio. Werten recht üppig ausfallen...
Und da ich dann, wie Du bereits sagtest, "nur" den Container finde, der gerade assertet, sollte ich´s erstmal mit ´ner Standardmethode (also op[]) versuchen...ist auch in ner viertel stunde schaffbar.
Naja, vielleicht auch ein bißchen länger ;-))
wenn das auch nicht hilft, mach ich dir den fehler für 100Eu/h weg. *g*
Na vielen Dank! ;-))
Btw, wie kann es überhaupt vorkommen, dass MSVC++ Zugriffe per iter über die Grenzen hinaus nicht entdeckt und zumindest zur Laufzeit meckert? Dass es beim op[] funktioniert und dann 0xffffffff Werte o.ä. angenommen werden, leuchtet ja noch ein, aber gerade um dem aus dem Weg zu gehen, habe ich wenn es ging iter verwendet...
Gruß,
Holger
-
edward schrieb:
Btw, wie kann es überhaupt vorkommen, dass MSVC++ Zugriffe per iter über die Grenzen hinaus nicht entdeckt und zumindest zur Laufzeit meckert? Dass es beim op[] funktioniert und dann 0xffffffff Werte o.ä. angenommen werden, leuchtet ja noch ein, aber gerade um dem aus dem Weg zu gehen, habe ich wenn es ging iter verwendet...
der vector<int> ist ja innendrin auch nur ein int* begin;int* end; und ein vector<int>::iterator ist auch nur ein int*.
wenn du auf so nem iterator op++ machst, ist das nur ein zeigerinkrement. das kannste weit über end hinausmachen und keienr merkts. ok, ist nicht soo wahrscheinloch, daß man es tut. aer ich weiß ja nicht, was du getan hast.viel schrecklicher sind aber die fehler dieser art:
vector<string> toDo="C:\";
for(vector<string>::iterator parent=toDo.begin();parent!=toDo.end();++parent){
vector<string> childs=readDirectory(*parent);
for(vector<string> child=childs.begin();child!=childs.end();++childs){
if(isDirectory(*child))
toDo.push_back(*child)
else
cout<<*child<<endl;
}
}durch das push_back wurden alle lebenden iteratoren, die irgendwo in toDo reinzeigen ungültig. immerhin hätte der conttauner ja beim push_back neuen speicher anlegen können.
mit op[] wäre das nicht passiert.
aber richtig gut wäre es gewesen, einen queue zu benutzen und die gelesenen parents auch gleich wegzupoppen.