Run-Time Check Failure #2 - Stack around the variable 'xyz' was corrupted



  • Ich habe schon in richtig vielen Foren und auch per Google-Suche nach der Fehlermeldung gesucht, aber nichts gefunden. Deswegen möchte ich noch einmal hier direkt mit meinem Code danach fragen.

    Meine main.cpp:

    #include "StdAfx.h"
    
    int main() {
    
    	Student xyz;
    	xyz.create("Peter","Mueller");
    
    	Student abc;
    	abc.create("Hannes","Schuster");
    
    	cout << "Welcher Schueler?" << endl;
    	cout << "1 oder 2?" << endl;
    	cout << "Bitte waehlen: " << endl;
    	int Choice;
    	cin >> Choice;
    
    	if(Choice==1)
    			{
    				xyz.showAll();
    			}
    	if(Choice==2)
    			{
    				abc.showAll();
    			}
    	if(Choice!=1 && Choice!=2)
    			{
    				cout << "Fail" << endl;
    			}
    	getch();
    	return 0;
    }
    

    Meine CreateStudent.cpp:

    //     CREATESTUDENT_CPP     //
    
    #include "StdAfx.h"
    
    //========== DEFINITION : CREATESTUDENT.CPP ==========//
    
    void Student::create(const char* VN, const char* N){
    
    	strncpy( szName, N, sizeof(szName)-1);
    	szName[sizeof(szName)]=NULL;
    
    	strncpy( szVorName, VN, sizeof(szVorName)-1);
    	szVorName[sizeof(szVorName)]=NULL;
    
    }
    
    void Student::showAll(){
    
    				cout << "Vorname: " << szVorName << endl;
    				cout << "Nachname: " << szName << endl;
    
    }
    
    void Student::setAll(){
    
    	char VN[30];
    	char N[50];
    
    	cout << "Vorname: ";
    	cin >> VN;
    	cout << "Nachname: ";
    	cin >> N;
    
    	strncpy( szName, N, sizeof(szName)-1);
    	szName[sizeof(szName)]=NULL;
    
    	strncpy( szVorName, VN, sizeof(szVorName)-1);
    	szVorName[sizeof(szVorName)]=NULL;
    
    }
    

    Meine CreateStudent.h:

    //     CREATESTUDENT_H     //
    
    #ifndef CREATESTUDENT_H
    #define CREATESTUDENT_H
    
    //========== DEKLARATION : CREATESTUDENT.H ==========//
    
    class Student{
    
    private:
    			//=====VARIABLEN=====//
    			char	szName[51];
    			char	szVorName[31];
    
    public:
    
    			//=====SET=====//
    			void create(const char* VN, const char* N);
    			void setAll();
    
    			//=====SHOW-FUNCTIONS=====//
    			void showAll();
    
    };
    
    #endif//CREATESTUDENT_H
    

    Und meine StdAfx.h(Vorkompilierter header in Visual Studio):

    //   STDAFX_H   //
    
    #ifndef STDAFX_H
    #define STDAFX_H
    
    //   INCLUDES   //
    
    #include <iostream>
    #include <conio.h>
    #include "CreateStudent.h"
    using namespace std;
    
    #endif//STDAFX_H
    

    Das Ziel des Programms ist es, den Namen mehrerer Schüler festzulegen und auszugeben. Der Code im Moment kann allerdings nur den Namen, nachdem gefragt wurde welcher ausgegeben werden soll, anzeigen. Trotzdem kommt die Fehlermeldung.

    Kann mir jemand helfen, wie ich den Fehler und die Meldung beseitige?

    Vielen Dank schon einmal im vorhinein.



  • Das grundsätzliche Problem ist, dass du char-Arrays anstatt std::string verwendest. Gibt es einen Grund dafür?



  • Edit:
    Vieles diesen Inhalts habe ich Flame Dev's Youtube Tutorials nachempfunden.

    Zumindest die Std...-Header-Datei und die sache mit dem CreateStudent.Create()



  • strncpy( szName, N, sizeof(szName)-1);
    szName[sizeof(szName)]=NULL;
    

    Undefined behaviour.
    Schaue dir mal std::string an.
    Oder:

    strncpy(szName, N, strlen(szName)+1);
    szName[strlen(szName)] = '\0';
    


  • Einen Grund nicht. Ich wusste es nicht besser aber ich werde es probieren. Müssen alle char durch std::sring ersetzt werden?

    Übrigens bin ich derselbe wie Stormrider13000



  • char char_string[max_size];
    ->
    std::string std_string;
    
    strcpy(char_string, "foo");
    ->
    std_string = "foo";
    
    if (strcmp(char_string, "foo") == 0)...
    ->
    if (std_string == "foo")...
    

    Also ganz intutiv behandeln, wie ints auch.
    Dazu noch Abfragen der Größe, find(), erase(), etc.
    Genaueres hier: http://en.cppreference.com/w/cpp/string/basic_string



  • Also ist mein Fehler, der, dass ich meine chars in strings umwandeln muss?



  • Nein, dein Fehler ist, dass du auf Zeichen zugreifen willst, die gar nicht mehr zu deinem String gehören.
    Mit std::string kann sowas nicht passieren.



  • Nathan schrieb:

    strncpy(szName, N, strlen(szName)+1);
    szName[strlen(szName)] = '\0';
    

    Wenn man sich zu lange mit std::string beschäftigt, wird man etwas nachlässig im Umgang mit char[] , was? 😉



  • Viiieeeelen Dank!!! Ich habe deinen Hinweis mit den Strings gemacht und nun klappts!
    Nochmals vielen Dank!



  • Furble Wurble schrieb:

    Nathan schrieb:

    strncpy(szName, N, strlen(szName)+1);
    szName[strlen(szName)] = '\0';
    

    Wenn man sich zu lange mit std::string beschäftigt, wird man etwas nachlässig im Umgang mit char[] , was? 😉

    Ähm, offenbar.
    Ich weiß noch nicht einmal, was du meinst. 😃



  • Nathan schrieb:

    Furble Wurble schrieb:

    Nathan schrieb:

    strncpy(szName, N, strlen(szName)+1);
    szName[strlen(szName)] = '\0';
    

    Wenn man sich zu lange mit std::string beschäftigt, wird man etwas nachlässig im Umgang mit char[] , was? 😉

    Ähm, offenbar.
    Ich weiß noch nicht einmal, was du meinst. 😃

    strncpy() darf eigentlich nur sizeof(szName)-1 Zeichen kopieren. strlen() geht schlecht, da szName ja u.U. noch nicht einmal nullterminiert ist.
    Und der Nullterminator muss an das Ende des kopierten Strings - auch da geht strlen() nicht, da man den Nullterminator ja gerade erst einfügt.
    Wahrscheinlich verbocke ich es jetzt auch, aber ich würde es vielleicht so machen:

    const size_t len = strlen(N) < sizeof(szName)-1 ? strlen(N) : sizeof(szName)-1;
    strncpy(szName, N, len);
    szName[len] = '\0';
    


  • Mit strings habe ich jetzt aber das Problem, das ich in meinem Fall z.B. keine Doppelnamen ohne Bindestrich speichern kann, da strings ja keine Leerzeichen speichern können. Gibt es dafür auch eine Lösung?



  • Natürlich können strings Leerzeichen speichern!

    std::string str = "Dies ist ein String mit Leerzeichen,\n Zeilenumbruechen,\t und Tabs";
    


  • Auch wenn ich einen String über die Konsole eingebe? Weil ich das Programm ausgeführt habe und dann einen String mit Leerzeichen für VN in der Funktion Student::setAll() eingegeben habe und garnicht mehr den String für N eingeben konnte.



  • std::getline



  • Danke 😉 Klappt jetzt



  • Storm13000 schrieb:

    Edit:
    Vieles diesen Inhalts habe ich Flame Dev's Youtube Tutorials nachempfunden.

    Zumindest die Std...-Header-Datei und die sache mit dem CreateStudent.Create()

    Du solltest dir besser ein vernünftiges Buch zulegen und daraus lernen. Es gibt im Forum eine FAQ dazu, schau´ mal rein.
    Wenn du deinen Code so geschrieben hast, wie es im Videotutorial erklärt wurde, dann lernst du nichts ordentliches. Der Code ist übelst gruselig...



  • Ok, ich habe mir bereits C++ von A bis Z von sowieso Wolf von Galileo Computing bestellt. Müsste die Tage ankommen.



  • Storm13000 schrieb:

    Ok, ich habe mir bereits C++ von A bis Z von sowieso Wolf von Galileo Computing bestellt. Müsste die Tage ankommen.

    Du hast aber auch ein Händchen für sowas? Bitte gleich zurückschicken. Das Buch taugt absolut nichts.


Log in to reply