Vector an Funktion übergeben -> Stack Überlauf
-
Hallo,
ich möchte einen std::vector an eine Funktion übergeben. Das ganze Funktioniert prima solange der vector nur ein Element beinhaltet.
Sobald mehr als ein Element im vector liegen bekomme ich vom Borland Turbo C++ einen Stack Überlauf gemeldet.
Der vector selbst speichert "unsigned long" Werte (also 4 Byte groß).Noch als Anmerkung: die Meldung kommt bei zwei Elementen, also denke ich nicht wirklich dass der Stack überläuft.
Im Moment sieht das so aus:
Funktionskopf:
string CParseFile::rekur(vector<u32> & vecDimensions, string strLine, u32 ulPosition)
Funktionsaufruf:
strDimensions = rekur( vecDimensions, strDimensions, 0);
p.s. Das ganze ist ne rekursive Funktion. Kann es damit was zu tun haben? (sollte eigentlich nicht da der Fehler direkt beim Aufruf geworfen wird, denke ich zumindest.)
-
Nun ja, rekursive Funktionen mit fehlernder oder falscher Abbruchbedingung ergeben grundsätzlich einen Stacküberlauf... Prüf mal die Abbruchbedingung(en).
-
Hallo
Rekursion und Stacküberlauf... das hängt meistens direkt zusammen. Denn jeder Funktionsaufruf wird ja auf dem Stack abgelegt. Je mehr verschachtelte Funktionsaufrufe du hast, desto knapper wird der beschränkte Platz auf dem Stack. Grade solche rekursive Funktionen die quasi unkontrolliert oft sich selber aufrufen enden meistens in Stacküberlauf.
Mit dem vector hat das nur insofern zu tun, das offenbar nach deinem Algo die Tiefe der rekursiven Aufrufe von der Anzahl der Elemente im vector abhängt.Es gibt wohl nur eine vollständige Lösung : Du must den Algo ändern (optimieren), am besten auf Rekursion verzichten und eine rein iterative Lösung in nur einem Funktionsaufruf verwenden.
bis bald
akari
-
Auf die Rekursive Funktion zu verzichten ist leider nicht möglich.
Eine Frage dazu habe ich aber trotzdem:
Die Funktion wird doch nichtmal ausgeführt wieso sollte ein Stacküberlauf also schon beim ersten(!) Aufruf(!) (nicht bei der Ausführung) stattfinden? Ich denke doch mal schwer dass mein Stack eine vector Referenz als Übergabeparameter überstehen sollte.
-
Hallo
Natürlich ist eine Referenz auf einen vector überhaupt nicht problematisch. Daran liegt ganz bestimmt nicht der Grund für einen Stacküberlauf.
Aus unserer Sicht können wir nur mögliche 2 Gründe sehen:
- Dein Algo ist fehlerhaft implementiert, und beendet sich nicht sondern ruft die Rekursion immer wieder auf
- Dein Algo ist korrekt implementiert, aber braucht beim korrekten Ablauf ab einer bestimmten Anzahl von Ausgangselementen zu viele DurchgängeDas ganze solltest du aber gut mit dem Debugger herausfinden können.
bis bald
akari
-
Brauche mehr Input!
Soll heißen: Zeige mehr Code!
-
Kurze Erklärung zu dem Teil:
Das Teil soll später Array Felder als String ausgeben also sprich: bei einem Array von den Dimensionen [2][2] -> [0][1],[1][0],[1][1] (Das erste Element [0][0] wird von Hand erzeugt und dient als Startwert für die folgenden Aufrufe siehe Beispiel).
Der Vector dient hierbei als dynamische Komponente zum Speichern der Arrayfeldgrößen und der Anzahl der Dimensionen (entspricht der vetor size)Beispiel:
der Vector beinhaltet zwei Elemente: vec[0] = 2 und vec[1] = 2
der String strLine sieht beim ersten Aufruf so aus: "[0][0]" und die Position ist 0
die Rückgabe ergibt: [0][1]
Der Nächste aufruf mit strLine = [0][1] ergibt: [1][0]
usw
wird die Fkt mit strLine = [1][1] aufgerufen ergibt sich: -[0][0]Gleich mal vorne weg: man verzeihe mir das Codegerümpel, ist alles noch Testphase aber zumindest für eindimensionale Arrays funktioniert es (von daher glaube ich schon dass die rekursion richtig sein
sollte
.) Noch was: Ich verwende teilweise die Boost Libary (zum casten etc)string CParseFile::rekur(vector<u32> & vecDimensions, string strLine, u32 ulPosition) { if ( (vecDimensions.size() - 1) <= ulPosition) // Im letzten Element angekommen { u32 ulTmpValue = strtol( (strLine.substr(1)).c_str(), NULL, 10); if ( (vecDimensions.at(ulPosition)) > ulTmpValue ) // Element ist erhöhbar { ulTmpValue++; string strResult = "["; strResult += boost::lexical_cast<string>(ulTmpValue); strResult += "]"; return strResult; } else // Element nicht weiter erhöhbar { return ( "-[0]" ); } } else { string strTmp = rekur( vecDimensions, strLine.substr( strLine.find("]")+1 ), ulPosition++); if ( strTmp[0] == '-' ) // Alle Unterelemente konnten nicht erhöht werden -> dieses Element muss erhöht werden falls möglich { strTmp = strTmp.substr(1); u32 ulTmpValue = strtol( (strLine.substr(1)).c_str(), NULL, 10); if ( vecDimensions.at(ulPosition) < ulTmpValue ) // Element ist erhöhbar { ulTmpValue++; string strResult = "["; strResult += ulTmpValue; strResult += "]"; strResult += strTmp; return strResult; } else // Element nicht weiter erhöhbar { return ( "-[0]" + strTmp ); } } else { u32 ulTmpValue = strtol( (strLine.substr(1)).c_str(), NULL, 10); string strResult = "["; strResult += ulTmpValue; strResult += "]"; strResult += strTmp; return strResult; } } }
-
Hallo
Editier mal deinen letzten Beispiel und mach aus den code-Tags cpp-Tags. Dann bekommst du auch Syntaxhighlightning.
Natürlich auch für die Zukunftbis bald
akari
-
Ich habe das mal getestet. ulPosition in Zeile 26 erhöht sich nicht, vllt ++ulPosition nehmen.
-
Schnelle Lieferung, Ware wie beschrieben, gerne wieder!
-> Vielen Dank, endlich kann ich weiter machen!
Zum Fehler: Wäre so ziemlich das letzte gewesen an das ich gedacht hätte. Er hat also doch die Rekursion durchgeführt, nur der Debugger hat mir davon nix erzählt :(. Kurz und knapp: Ihr hattet Recht!
edit: Das Teil läuft nochnicht ganz so wie es soll sehe ich gerade. Ihr braucht mich nicht drauf aufmerksam machen ^^
-
Falls es noch jemanden interessiert oder falls es einer braucht. Inzwischen ist es soweit fertig und funktioniert.
Noch was zur Problemlösung: Nur "++ulPosition" zu verwenden funktioniert auch nicht da die Variable nur in der Unterfunktion erhöht werden darf.
string CParseFile::rekur(vector<u32> & vecDimensions, string strLine, u32 ulPosition) { if ( (vecDimensions.size() - 1) <= ulPosition) // Im letzten Element angekommen { u32 ulTmpValue = strtol( (strLine.substr(1)).c_str(), NULL, 10); if ( ((vecDimensions.at(ulPosition)) - 1) > ulTmpValue ) // Element ist erhöhbar { ulTmpValue++; return ("[" + boost::lexical_cast<string>(ulTmpValue) + "]" ); } else // Element nicht weiter erhöhbar { return ( "-[0]" ); } } else { u32 tmpPosition = ulPosition; ++ulPosition; string strTmp = rekur( vecDimensions, strLine.substr( strLine.find("]")+1 ), ulPosition); if ( strTmp[0] == '-' ) // Alle Unterelemente konnten nicht erhöht werden -> dieses Element muss erhöht werden falls möglich { strTmp = strTmp.substr(1); u32 ulTmpValue = strtol( (strLine.substr(1)).c_str(), NULL, 10); if ( ((vecDimensions.at(tmpPosition)) - 1) > ulTmpValue ) // Element ist erhöhbar { ulTmpValue++; strTmp.insert(0, ("[" + boost::lexical_cast<string>(ulTmpValue) + "]") ) ; return strTmp; } else { return ("-[" + strTmp); } } else { u32 ulTmpValue = strtol( (strLine.substr(1)).c_str(), NULL, 10); strTmp.insert(0, ("[" + boost::lexical_cast<string>(ulTmpValue) + "]") ) ; return strTmp; } } }