Pufferüberlauf / Stack around the variable 'x' is corrupted
-
Hi
Der Titel sagts schon aus, hab erst vor nen paar Wochen mit C++ angefangen und habe nun ein kleines Programm geschrieben, das mithilfe von Int-Arrays aus 1-en und 0-en Zahlen und andere pixelartige Bilder ausgeben kann. Leider tritt beim Beenden des Programmes diese beiden Fehler im Titel auf. Ich habe keine Ahnung, was mir da für ein Fehler unterlaufen ist, und deswegen suche ich hier Hilfe. Wäre echt nett, wenn mir hier jemand helfen könnte und generelle Verbesserungsvorschläge zur Disskussion bringen könnte, man muss das ja net alles lesen, überfliegen sollte (für euch) reichen
renderscreen.h:
#include <iostream>
#include <time.h>class renderscreen { public: renderscreen(); void sleep(unsigned int mseconds); void createRectangle(int posX, int posY, int height, int width); void createNumber(int number); void printOut(); void clear(); void countDown(); private: int renderScreen[40][30]; //width("Breite") = 800, umgekehrt, weil [0][0] bei Initialisation jeweils +1 };renderscreen.cpp: #include "renderscreen.h" renderscreen::renderscreen() { std::cout << "Screen is in rendering-mode" << std::endl; for(int y = 40; y > 0;) { for(int x = 30; x > 0;) { renderScreen[y][x] = 0; x--; } y--; } } void renderscreen::createRectangle(int posX, int posY, int height, int width) { renderScreen[posY][posX] = 1; int widthA = width; while(height > 0) { while(width > 0) { renderScreen[height + (posY -1)][width + (posX - 1)] = 1; width--; } width = widthA; height--; } } void renderscreen::printOut() { for(int y = 1; y < 40;) { for(int x = 1; x < 30;) { std::cout << renderScreen[y][x] << " "; x++; } std::cout << "" << std::endl; y++; } } void renderscreen::clear() { memset(renderScreen, 0, sizeof(renderScreen)); } void renderscreen::createNumber(int number) { if(number == 0) { this->renderscreen::createRectangle(3, 6, 11, 4); //Top-left /*11, 4 ---> 3 = 2 über Oberkante (inkl. 0, die nicht ausgegeben wird) */ this->renderscreen::createRectangle(3, 23, 11, 4); //Down-left this->renderscreen::createRectangle(9, 36, 4, 11); //Down-middle this->renderscreen::createRectangle(22, 6, 11, 4); //Top-right this->renderscreen::createRectangle(22, 23, 11, 4); //Down-right this->renderscreen::createRectangle(9, 1, 4, 11); //Top-middle } if(number == 1) { this->renderscreen::createRectangle(22, 6, 11, 4); //Top-right this->renderscreen::createRectangle(22, 23, 11, 4); //Down-right } if(number == 2) { this->renderscreen::createRectangle(3, 23, 11, 4); //Down-left this->renderscreen::createRectangle(9, 36, 4, 11); //Down-middle this->renderscreen::createRectangle(22, 6, 11, 4); //Top-right this->renderscreen::createRectangle(9, 1, 4, 11); //Top-middle this->renderscreen::createRectangle(9, 18, 4, 11); //Middle-middle } if(number == 3) { this->renderscreen::createRectangle(9, 36, 4, 11); //Down-middle this->renderscreen::createRectangle(22, 6, 11, 4); //Top-right this->renderscreen::createRectangle(22, 23, 11, 4); //Down-right this->renderscreen::createRectangle(9, 1, 4, 11); //Top-middle this->renderscreen::createRectangle(9, 18, 4, 11); //Middle-middle } if(number == 4) { this->renderscreen::createRectangle(3, 6, 11, 4); //Top-left this->renderscreen::createRectangle(22, 6, 11, 4); //Top-right this->renderscreen::createRectangle(22, 23, 11, 4); //Down-right this->renderscreen::createRectangle(9, 18, 4, 11); //Middle-middle } if(number == 5) { this->renderscreen::createRectangle(3, 6, 11, 4); //Top-left this->renderscreen::createRectangle(9, 36, 4, 11); //Down-middle this->renderscreen::createRectangle(22, 23, 11, 4); //Down-right this->renderscreen::createRectangle(9, 1, 4, 11); //Top-middle this->renderscreen::createRectangle(9, 18, 4, 11); //Middle-middle } if(number == 6) { this->renderscreen::createRectangle(3, 6, 11, 4); //Top-left this->renderscreen::createRectangle(3, 23, 11, 4); //Down-left this->renderscreen::createRectangle(9, 36, 4, 11); //Down-middle this->renderscreen::createRectangle(22, 23, 11, 4); //Down-right this->renderscreen::createRectangle(9, 1, 4, 11); //Top-middle this->renderscreen::createRectangle(9, 18, 4, 11); //Middle-middle } if(number == 7) { this->renderscreen::createRectangle(22, 6, 11, 4); //Top-right this->renderscreen::createRectangle(22, 23, 11, 4); //Down-right this->renderscreen::createRectangle(9, 1, 4, 11); //Top-middle } if(number == 8) { this->renderscreen::createRectangle(3, 6, 11, 4); //Top-left this->renderscreen::createRectangle(3, 23, 11, 4); //Down-left this->renderscreen::createRectangle(9, 36, 4, 11); //Down-middle this->renderscreen::createRectangle(22, 6, 11, 4); //Top-right this->renderscreen::createRectangle(22, 23, 11, 4); //Down-right this->renderscreen::createRectangle(9, 1, 4, 11); //Top-middle this->renderscreen::createRectangle(9, 18, 4, 11); //Middle-middle } if(number == 9) { this->renderscreen::createRectangle(3, 6, 11, 4); //Top-left this->renderscreen::createRectangle(9, 36, 4, 11); //Down-middle this->renderscreen::createRectangle(22, 6, 11, 4); //Top-right this->renderscreen::createRectangle(22, 23, 11, 4); //Down-right this->renderscreen::createRectangle(9, 1, 4, 11); //Top-middle this->renderscreen::createRectangle(9, 18, 4, 11); //Middle-middle } } void renderscreen::sleep(unsigned int mseconds) { clock_t goal = mseconds + clock(); while (goal > clock()); } void renderscreen::countDown() { int v = 9; while(v > -1) { this->renderscreen::clear(); this->renderscreen::createNumber(v); this->renderscreen::sleep(1000); this->renderscreen::printOut(); std::cout << "________________________________________________________" << std::endl; v--; } }main.cpp: #include <iostream> #include "renderscreen.h" using namespace std; int main() { bool allowed = false; renderscreen screen; int numberSel; cout << "Creating rectangle..." << endl; screen.createRectangle(1, 1, 10, 20); // Syntax int posX(Left/Right) int posY(Up/Down) int height(Up/Down(Size)) width(Left/Right(Size)) screen.printOut(); // Screen displays cout << "Press a button to continue..." << endl; cin.sync(); cin.get(); screen.clear(); cout << "Creating a number. Please write a number from 0 - 9: " << endl; cin >> numberSel; cout << "Creating number..." << endl; screen.createNumber(numberSel); screen.printOut(); cout << "Press a button to continue" << endl; cin.sync(); cin.get(); cout << "Counting from 9 - 1..." << endl; screen.countDown(); cout << "Hope you liked my little program for an array-renderengine, im gonna make some funny animations and maybe a little game :D" << endl; cin.sync(); cin.get(); }
-
Hallo,
editier mal bitte deinen Eintrag und pack den Code in Code tags und formatier ein wenig.
-
-
TGGC schrieb:
Ja, real programmers nehmen immer mehr ab. Der Einzige der zunimmt scheine ich zu sein.
-
Geh es systematisch an.
- irgendwas stimmt mit x nicht
- wo verwendest du x?
- was ist ein Puffer?
- was ist ein Pufferüberlauf?
(- wie provoziert man den und ist das eventuell sogar ein häufiges Problem?)
- schreibst du etwa über den Puffer hinaus?Bingo!
-
[quote="Ruvi"]Hallo,
editier mal bitte deinen Eintrag und pack den Code in Code tags und formatier ein wenig.[/quote]
Werd ich machen
-
[quote="Ruvi"]Hallo,
editier mal bitte deinen Eintrag und pack den Code in Code tags und formatier ein wenig.[/quote]
Ach ja und wie geht das? mit dem Code-tag komme ich net so wirklich klar
-
[quote="asdfgh.."]Geh es systematisch an.
- irgendwas stimmt mit x nicht
- wo verwendest du x?
- was ist ein Puffer?
- was ist ein Pufferüberlauf?
(- wie provoziert man den und ist das eventuell sogar ein häufiges Problem?)
- schreibst du etwa über den Puffer hinaus?Bingo![/quote]
Hab ich schon. Wie auf etlichen anderen Websites auf denen ich schon Hilfe gesucht habe habe ich wie hier nur gesagt bekommen, wie ich es mache, was aber nie funktioniert. Dann gehe ich mal wieder auf eine andere Website, weil ich hier scheinbar auch keine wirkliche Hilfe bekommen...
-
Basti153 schrieb:
Der Titel sagts schon aus [...] Ich habe keine Ahnung, was mir da für ein Fehler unterlaufen ist, und deswegen suche ich hier Hilfe.
Pufferüberlauf nennt man die Fehler, wo man eigentlich auf einen bestimmten Speicherbereich zugreifen will, dann aber dabei "daneben langt", z.B. mit ungültigen Array-Indizes. Genau das hast Du gemacht, wobei der "Puffer" hier dein
renderScreenist. Guck dir an, was für x- und y-Werte du verwendest. Davon sind nicht alle erlaubt.
-
[quote="krümelkacker"][quote="Basti153"]
Der Titel sagts schon aus [...] Ich habe keine Ahnung, was mir da für ein Fehler unterlaufen ist, und deswegen suche ich hier Hilfe.
[/quote]
Pufferüberlauf nennt man die Fehler, wo man eigentlich auf einen bestimmten Speicherbereich zugreifen will, dann aber dabei "daneben langt", z.B. mit ungültigen Array-Indizes. Genau das hast Du gemacht, wobei der "Puffer" hier deinrenderScreenist. Guck dir an, was für x- und y-Werte du verwendest. Davon sind nicht alle erlaubt.[/quote]
Danke, so eine Antwort habe ich gesucht
-
Wie merkbefreit bist du eigentlich?
Aktivier mal BBCode bei deinen Beiträgen.
-
Basti153 schrieb:
Hab ich schon. Wie auf etlichen anderen Websites auf denen ich schon Hilfe gesucht habe habe ich wie hier nur gesagt bekommen, wie ich es mache, was aber nie funktioniert.
Ich habe dir eine Anleitung zur Fehlerbehebung in die Hand gegeben, weil du davon im Moment (einige Wochen C++ Erfahrung) am meisten profitierst. Wenn du die geposteten Punkte selbst bearbeitest, dann hilft dir das langfristig. Solltest du nach eigener Recherche Fragen zu den Punkten haben, dann nur her damit.
(Falls es dich interessiert, es gibt zu dem Fehler sogar einen ganzen Eintrag in der deutschen Wikipedia: Off-by-one-Error.)
-
Basti153, statt mit "rohen Arrays" à la
int[6]kannst du auch mitarray<int,6>aus demstd-Namensraum arbeiten. Das gibt es seit C++11. Es bietet Dir typischerweise – zumindest mit g++/libstdc++ – auch einen netten Debug-Modus an, der dir dann solche Fehler wie ungültige Indizes schon viel früher abfängt. Versuche am besten rohe Arrays und Zeiger zu vermeiden. Wie du gemerkt hast, ist das fehleranfällig.Statt Zeiger bräuchten wir eigentlich so etwas wie eine standardisierte Familie von
array_view-Typen, die auch einen solchen Debug-Modus anbieten. Denn oft sieht man ja Funktionen, die Zeiger + Länge übergeben bekommen. Das sollte IMHO ein einziger Parameter sein. In anderen Sprachen gibt's das ja auch oft unter dem Namen "slice". Ich habe mir so etwas selbst nachgebaut (allerdings ohne "checked iterators"). Dieses Klassentemplate erlaubt dann z.B. folgenden Code:void anzeigen(slice<const int> s) { while (s) { std::cout << s.shift_ref() << std::endl; // quasi *ptr++ Äquivalent } } int main() { int feld[] = {1,2,3,4,5}; std::vector<int> vektor = {1,2,3,4,5,6,7,8,9}; anzeigen(feld); // 1 bis 5 anzeigen(vektor); // 1 bis 9 anzeigen(const_all_of(vektor).slice_from(4)); // 5 bis 9 }Ich weiß, dass ich nicht perfekt bin, also überlasse ich das "Indexgeprüfe" lieber
slice<T>im Debugmodus.Warum keine Iteratoren? Weil mich Iteratoren, zumindest das, was man in C++ darunter versteht, nerven! Lineares Speicherlayout kommt zudem bei mir recht oft vor. Mein
sliceist quasi ein Spezialfall einer "Alexandrescu-Range" für lineares Elementen-Layout. Was die letzten Ideen von Eric Niebler in der Richtung angehen, da bin ich leider nicht auf dem aktuellen Stand.Und weil das so schön zum Thema Speichersicherheit passt hier noch ein Tipp: Rust 1.0.0-beta.2 ist jetzt veröffentlicht worden.
SCNR