Problem mit dynamischem Struktur-Array



  • Hi Leute,

    wir sollen im Programmierunterricht ein kleines Programm schreiben, in das wir die Daten eines Mitarbeiters (Name, Alter, Ehestand und Gehalt) eintragen können. Diese Daten sollen, nachdem man genügend Mitarbeiter angelegt wurden, angezeigt werden.

    Ich bin eigentlich schon so gut wie fertig, aber ich habe ein kleines Problem. Das Array für die Mitarbeiter soll dynamisch sein, also muss man Speicher auf dem Heap anfordern. Ich habe das bisher so gelöst:

    // Header-Dateien
    #include <iostream>
    using namespace std;
    
    // Struktur: Mitarbeiter
    // Aufg.: Speichert die Informationen der Mitarbeiter
    struct SMitarbeiter
    {
    	bool   verheiratet;			// für den Ehestand
    	int    alter;				// für das Alter
    	float  gehalt;				// für das Gehalt
    	char   name[20];			// für den Nachnamen
    };
    
    // Hauptfunktion
    int main(void)
    {
    	// deklarieren der benötigten Variablen
    	char weiter, verheiratet;
    	int i = 0;
    
    	// läuft solange, bis Benutzer keine weitere
    	// Eingabe verlangt
    	do
    	{
    		// Speicher anfordern
    		SMitarbeiter* pMitarbeiter[100] = new SMitarbeiter; // Hier bekomm ich einen Fehler
    
    		// Eingabe
    		// Wie heißt der Mitarbeiter?
    		cout << "Name des " << (i + 1) << ". Mitarbeiter: ";
    		cin >> pMitarbeiter[i]->name;
    
    		// Wie alt ist der Mitarbeiter?
    		cout << "Alter des " << (i + 1) << ". Mitarbeiter: ";
    		cin >> pMitarbeiter[i]->alter;
    
    		// Ist der Mitarbeiter verheiratet?
    		cout << "Ist Mitarbeiter " << (i + 1) << " verheiratet? ";
    		cin >> verheiratet;
    
    		if(verheiratet == 'j' || verheiratet == 'J')
    			pMitarbeiter[i]->verheiratet = true;			// ja, ist er
    		else if(verheiratet == 'n' || verheiratet == 'N')
    			pMitarbeiter[i]->verheiratet = false;			// nein, ist er nicht
    
    		// Wie viel Gehalt bekommt der Mitarbeiter?
    		cout << "Gehalt des " << (i + 1) << ". Mitarbeiter: ";
    		cin >> pMitarbeiter[i]->gehalt;
    
    		// weitere Mitarbeiter hinzufügen
    		cout << "weitere Mitarbeiter (j/n)? ";
    		cin >> weiter;
    
    		// i inkrementieren
    		i++;
    	} while(weiter == 'j');
    
            // Ausgeben der Mitarbeiterdaten
            ...
    
    	return 0;
    }
    

    Wenn ich das Programm bis dahin kompiliere, erhalte ich im VC++6 folgenden Fehler:

    error C2440: 'initializing' : 'struct SMitarbeiter *' kann nicht in 'struct SMitarbeiter *[100]' konvertiert werden
            Es gibt keine Konvertierungen von Feldtypen, obwohl es Konvertierungen von Verweisen oder Zeigern in Felder gibt
    

    Ich hab keine Ahnung, woran das liegen kann. Hab schon einiges versucht, bin aber immer wieder gescheitert. Ich hoffe ihr könnt mir helfen.

    Danke schonmal...

    MfG Apo



  • die syntax muss so aussehen:

    SMitarbeiter* pMitarbeiter = new SMitarbeiter[100];
    

    Und vergiss am ende nicht ein:

    delete[] pMitarbeiter;
    

    damit der speicher wieder freigegeben wird.

    mfg.



  • Danke..., nun funktioniert es! ^^

    MfG Apo



  • okay..., es funktioniert doch noch nicht ganz. Mein Programm sieht nun so aus:

    // Header-Dateien
    #include <iostream>
    using namespace std;
    
    // Struktur: Mitarbeiter
    // Aufg.: Speichert die Informationen der Mitarbeiter
    struct SMitarbeiter
    {
    	bool   verheiratet;			// für den Ehestand
    	int    alter;				// für das Alter
    	float  gehalt;				// für das Gehalt
    	char   name[20];			// für den Nachnamen
    };
    
    // Hauptfunktion
    int main(void)
    {
    	// deklarieren der benötigten Variablen
    	char weiter, verheiratet;
    	int i = 0, j;
    	SMitarbeiter* pMitarbeiter[100];
    
    	// läuft solange, bis Benutzer keine weitere
    	// Eingabe verlangt
    	do
    	{
    		// Speicher anfordern
    		pMitarbeiter[i] = new SMitarbeiter;
    
    		// Eingabe
    		// Wie heißt der Mitarbeiter?
    		cout << "Name des " << (i + 1) << ". Mitarbeiter: ";
    		cin >> pMitarbeiter[i]->name;
    
    		// Wie alt ist der Mitarbeiter?
    		cout << "Alter des " << (i + 1) << ". Mitarbeiter: ";
    		cin >> pMitarbeiter[i]->alter;
    
    		// Ist der Mitarbeiter verheiratet?
    		cout << "Ist Mitarbeiter " << (i + 1) << " verheiratet? ";
    		cin >> verheiratet;
    
    		if(verheiratet == 'j' || verheiratet == 'J')
    			pMitarbeiter[i]->verheiratet = true;			// ja, ist er
    		else if(verheiratet == 'n' || verheiratet == 'N')
    			pMitarbeiter[i]->verheiratet = false;
    
    		// Wie viel Gehalt bekommt der Mitarbeiter?
    		cout << "Gehalt des " << (i + 1) << ". Mitarbeiter: ";
    		cin >> pMitarbeiter[i]->gehalt;
    
    		// weitere Mitarbeiter hinzufügen
    		cout << "weitere Mitarbeiter (j/n)? ";
    		cin >> weiter;
    
    		// i inkrementieren
    		i++;
    		cout << endl;
    	} while(weiter == 'j');
    
    	// Daten ausgeben
    	for(j = 0; j < i; j++)
    	{
    		cout << endl << "Name:\t" << pMitarbeiter[j]->name << endl;
    		cout << "Alter:\t" << pMitarbeiter[j]->alter << endl;
    		cout << "Verheiratet:\t";
    		if(pMitarbeiter[j]->verheiratet == true)
    			cout << "Ja" << endl;
    		else
    			cout << "Nein" << endl;
    		cout << "Gehalt:\t" << pMitarbeiter[j]->gehalt << " EUR" << endl;
    	}
    
    	// Speicher wieder freigeben
    	delete[] pMitarbeiter;
    
    	return 0;
    }
    

    Ich kann nun all meine Daten eingeben und sie werden auch richtig ausgegeben, aber ich bekomme, wenn die Zeile:

    delete[] pMitarbeiter;
    

    erreicht wird einen Exception-Fehler. Greife ich beim löschen auf ein nicht bestehendes Array zu? Ich sag ihm doch, dass er das ganze Array löschen soll. Ich hoffe ihr könnt mir erneut helfen.

    MfG Apo



  • Du hast das ein bischen verdreht.

    SMitarbeiter* pMitarbeiter[100];
    

    erzeugt ein statisches Array mit 100 Elementen vom Typ Zeiger auf SMitarbeiter. Du willst ja sicher ein dynamisches Array auf SMitarbeiter.
    Also

    SMitarbeiter* pMitarbeiter = new pMitarbeiter[100];
    

    dann noch

    pMitarbeiter[i] = new SMitarbeiter;
    

    weglassen und es sollte gehen. Du solltest in deiner while-Schleife noch prüfen ob du die Arraygrenzen (100) nicht überschreitest.



  • Wenn ich es so mache, wie du es geschrieben hast, dann bekomme ich 102 Fehler um die Ohren geschmiessen. Hab ich etwas falsch verstanden?

    // Header-Dateien
    #include <iostream>
    using namespace std;
    
    // Struktur: Mitarbeiter
    // Aufg.: Speichert die Informationen der Mitarbeiter
    struct SMitarbeiter
    {
    	bool   verheiratet;			// für den Ehestand
    	int    alter;				// für das Alter
    	float  gehalt;				// für das Gehalt
    	char   name[20];			// für den Nachnamen
    };
    
    // Hauptfunktion
    int main(void)
    {
    	// deklarieren der benötigten Variablen
    	char weiter, verheiratet;
    	int i = 0, j;
    	SMitarbeiter* pMitarbeiter = new pMitarbeiter[100];
    
    	// läuft solange, bis Benutzer keine weitere
    	// Eingabe verlangt
    	do
    	{
    		// Speicher anfordern
    		pMitarbeiter[i] = new SMitarbeiter;
    
    		// Eingabe
    		// Wie heißt der Mitarbeiter?
    		cout << "Name des " << (i + 1) << ". Mitarbeiter: ";
    		cin >> pMitarbeiter[i]->name;
    
    		// Wie alt ist der Mitarbeiter?
    		cout << "Alter des " << (i + 1) << ". Mitarbeiter: ";
    		cin >> pMitarbeiter[i]->alter;
    
    		// Ist der Mitarbeiter verheiratet?
    		cout << "Ist Mitarbeiter " << (i + 1) << " verheiratet? ";
    		cin >> verheiratet;
    
    		if(verheiratet == 'j' || verheiratet == 'J')
    			pMitarbeiter[i]->verheiratet = true;			// ja, ist er
    		else if(verheiratet == 'n' || verheiratet == 'N')
    			pMitarbeiter[i]->verheiratet = false;
    
    		// Wie viel Gehalt bekommt der Mitarbeiter?
    		cout << "Gehalt des " << (i + 1) << ". Mitarbeiter: ";
    		cin >> pMitarbeiter[i]->gehalt;
    
    		// weitere Mitarbeiter hinzufügen
    		cout << "weitere Mitarbeiter (j/n)? ";
    		cin >> weiter;
    
    		// i inkrementieren
    		i++;
    		cout << endl;
    	} while(weiter == 'j');
    
    	// Daten ausgeben
    	for(j = 0; j < i; j++)
    	{
    		cout << endl << "Name:\t" << pMitarbeiter[j]->name << endl;
    		cout << "Alter:\t" << pMitarbeiter[j]->alter << endl;
    		cout << "Verheiratet:\t";
    		if(pMitarbeiter[j]->verheiratet == true)
    			cout << "Ja" << endl;
    		else
    			cout << "Nein" << endl;
    		cout << "Gehalt:\t" << pMitarbeiter[j]->gehalt << " EUR" << endl;
    	}
    
    	// Speicher wieder freigeben
    	delete[] pMitarbeiter;
    
    	cin.get();
    	cin.get();
    	return 0;
    }
    

    MfG Apo



  • hi,
    ALSO das:

    Braunstein schrieb:

    Also

    SMitarbeiter* pMitarbeiter = new pMitarbeiter[100];
    

    is totaler Quatsch... 😃 denn pMitarbeiter ist kein Typ. Also so sieht die Syntax für die dynamische Speicherreserviereung aus:

    Typ* pName = new Typ[Value];
    

    Dabei ist...
    Typ ein elementarer Datentyp oder ein Objekt einer Klasse/Struct/Union/etc.
    ...und...
    Value ein ganzzahliger Ausdruck; ungleich 0!

    ALSO in deinem Fall:

    SMitarbeiter* pMitarbeiter = new SMitarbeiter[100];
    

    so und das solltest du auch in deinen Code mal einbinden... 😉

    glaub du verwirrst hier alle... 😃 😃

    Hoffe das war verständlich 🙄 -> 😉

    MfG CodeFinder



  • hier der !!ansatzweise!! korrigierte Code

    // Header-Dateien
    #include <iostream>
    using namespace std;
    
    #define MAX_MITARBEITER 100
    
    // Struktur: Mitarbeiter
    // Aufg.: Speichert die Informationen der Mitarbeiter
    struct SMitarbeiter
    {
        bool   verheiratet;            // für den Ehestand
        int    alter;                // für das Alter
        float  gehalt;                // für das Gehalt
        char   name[20];            // für den Nachnamen
    };
    
    // Hauptfunktion
    int main(void)
    {
        // deklarieren der benötigten Variablen
        char weiter, verheiratet;
        int i = 0, j;
        // Speicher anfordern
        SMitarbeiter* pMitarbeiter = new SMitarbeiter[MAX_MITARBEITER];
    
        // läuft solange, bis Benutzer keine weitere
        // Eingabe verlangt
        do
        {
            // Eingabe
            // Wie heißt der Mitarbeiter?
            cout << "Name des " << (i + 1) << ". Mitarbeiter: ";
            cin >> pMitarbeiter[i]->name;
    
            // Wie alt ist der Mitarbeiter?
            cout << "Alter des " << (i + 1) << ". Mitarbeiter: ";
            cin >> pMitarbeiter[i]->alter;
    
            // Ist der Mitarbeiter verheiratet?
            cout << "Ist Mitarbeiter " << (i + 1) << " verheiratet? ";
            cin >> verheiratet;
    
            if(verheiratet == 'j' || verheiratet == 'J')
                pMitarbeiter[i]->verheiratet = true;            // ja, ist er
            else if(verheiratet == 'n' || verheiratet == 'N')
                pMitarbeiter[i]->verheiratet = false;
    
            // Wie viel Gehalt bekommt der Mitarbeiter?
            cout << "Gehalt des " << (i + 1) << ". Mitarbeiter: ";
            cin >> pMitarbeiter[i]->gehalt;
    
            // weitere Mitarbeiter hinzufügen
            cout << "weitere Mitarbeiter (j/n)? ";
            cin >> weiter;
    
            // i inkrementieren
            i++;
            if(i == MAX_MITARBEITER - 1)
               break;
            cout << endl;
        } while(weiter == 'j');
    
        // Daten ausgeben
        for(j = 0; j < i; j++)
        {
            cout << endl << "Name:\t" << pMitarbeiter[j]->name << endl;
            cout << "Alter:\t" << pMitarbeiter[j]->alter << endl;
            cout << "Verheiratet:\t";
            if(pMitarbeiter[j]->verheiratet == true)
                cout << "Ja" << endl;
            else
                cout << "Nein" << endl;
            cout << "Gehalt:\t" << pMitarbeiter[j]->gehalt << " EUR" << endl;
        }
    
        // Speicher wieder freigeben
        delete[] pMitarbeiter;
    
        cin.get();
        cin.get();
        return 0;
    }
    

    ...der dürfte zwar funktionieren(nicht getestet!) aber da ist -genau genommen- nix dynamisch...
    bin mir nicht ganz sicher was du mit deinem Code erreichen wills,
    aber wenn es das is was ich denke (so viele Mitarbeiter einlesen wie der User
    es möchte und Array je nach Wunsch vergrößern), dann is das n bissl mehr Arbeit:
    Du musst ein Temparray erstellen, darin die Daten des Hauptarrays zwischenspeichern...
    dann das Hauptarray freigeben neu reservieren
    (diesmal ein Element mehr) dann die daten des Temparrays wieder ins
    Hauptarray kopieren und das neue Element anhängen (ans Hauptarray);
    anschließend das Temparray wieder freigeben...
    dazu hatte ich jetzt keine Lust mehr 🙄 ...

    Hoffe das war verständlich und trifft deine Intention 😉 ....

    MfG CodeFinder



  • Dann baue doch dein Programm in etwa so um:

    //...
    int main(void)
    {
        // deklarieren der benötigten Variablen
        char weiter, verheiratet;
        int i = 0, j;
        int Anzahl = 0;
    
        //wieviele Mitarbeiter?
        cout<<"wieviele Mitarbeiter wollen sie eingeben?"<<endl;
        cin>>Anzahl;
        // Speicher anfordern
        SMitarbeiter* pMitarbeiter = new SMitarbeiter[Anzahl];
    
        // läuft solange, bis Benutzer keine weitere
        // Eingabe verlangt
        for(i = 0; i < Anzahl; i++)
        {
            // Eingabe
            // Wie heißt der Mitarbeiter?
            cout << "Name des " << (i + 1) << ". Mitarbeiter: ";
            cin >> pMitarbeiter[i]->name;
    
            // Wie alt ist der Mitarbeiter?
            cout << "Alter des " << (i + 1) << ". Mitarbeiter: ";
            cin >> pMitarbeiter[i]->alter;
    //...
    


  • // Header-Dateien
    #include <iostream>
    #include <vector>
    using namespace std;
    
    // Struktur: Mitarbeiter
    // Aufg.: Speichert die Informationen der Mitarbeiter
    struct SMitarbeiter
    {
    	bool   verheiratet;			// für den Ehestand
    	int    alter;				// für das Alter
    	float  gehalt;				// für das Gehalt
    	char   name[20];			// für den Nachnamen
    };
    
    // Hauptfunktion
    int main(void)
    {
    	// deklarieren der benötigten Variablen
    	char weiter, verheiratet;
    	int i = 0, j;
    
        vector<SMitarbeiter*> pMitarbeiter;
    
    	// läuft solange, bis Benutzer keine weitere
    	// Eingabe verlangt
    	do
    	{
    		// Speicher anfordern und in vector packen
    		pMitarbeiter.push_back(new SMitarbeiter);
    
    		// Eingabe
    		// Wie heißt der Mitarbeiter?
    		cout << "Name des " << (i + 1) << ". Mitarbeiter: ";
    		cin >> pMitarbeiter[i]->name;
    
    		// Wie alt ist der Mitarbeiter?
    		cout << "Alter des " << (i + 1) << ". Mitarbeiter: ";
    		cin >> pMitarbeiter[i]->alter;
    
    		// Ist der Mitarbeiter verheiratet?
    		cout << "Ist Mitarbeiter " << (i + 1) << " verheiratet? ";
    		cin >> verheiratet;
    
    		if(verheiratet == 'j' || verheiratet == 'J')
    			pMitarbeiter[i]->verheiratet = true;			// ja, ist er
    		else if(verheiratet == 'n' || verheiratet == 'N')
    			pMitarbeiter[i]->verheiratet = false;
    
    		// Wie viel Gehalt bekommt der Mitarbeiter?
    		cout << "Gehalt des " << (i + 1) << ". Mitarbeiter: ";
    		cin >> pMitarbeiter[i]->gehalt;
    
    		// weitere Mitarbeiter hinzufügen
    		cout << "weitere Mitarbeiter (j/n)? ";
    		cin >> weiter;
    
    		// i inkrementieren
    		i++;
    		cout << endl;
    	} while(weiter == 'j');
    
    	// Daten ausgeben
    	for(j = 0; j < i; j++)
    	{
    		cout << endl << "Name:\t" << pMitarbeiter[j]->name << endl;
    		cout << "Alter:\t" << pMitarbeiter[j]->alter << endl;
    		cout << "Verheiratet:\t";
    		if(pMitarbeiter[j]->verheiratet == true)
    			cout << "Ja" << endl;
    		else
    			cout << "Nein" << endl;
    		cout << "Gehalt:\t" << pMitarbeiter[j]->gehalt << " EUR" << endl;
    	}
    
    	// Speicher wieder freigeben
    	vector<SMitarbeiter*>::iterator it = pMitarbeiter.begin();
        while(it != pMitarbeiter.end()) {
                   delete *it;
                   ++it;
        } 
    
    	cin.get();
    	cin.get();
    	return 0;
    }
    


  • An die STL'ianer:

    Bringt das:

    vector<SMitarbeiter*>::iterator it_start = pMitarbeiter.begin();
    vector<SMitarbeiter*>::iterator it_end = pMitarbeiter.end();
    
    while(it_start != it_end) {
               delete *it_start;
               ++it_start;
    }
    

    Im gegensatz zu dem hier einen größeren Vorteil:

    vector<SMitarbeiter*>::iterator it = pMitarbeiter.begin();
    
    while(it != pMitarbeiter.end()) {
               delete *it;
               ++it;
    }
    


  • @CodeFinder
    Warum so aufgeregt. Man kann sich doch mal verschreiben.



  • @Freak: Ich würde mal sagen, der obere dürfte schneller sein, weil du im zweiten Beispiel für jeden Durchlauf einen Aufruf von end() hast (aber gute Compiler optimieren diesen Aufruf durch inline-Funktionen - da fällt der ZUsatzaufwand dann wieder weg).



  • CStoll schrieb:

    @Freak: Ich würde mal sagen, der obere dürfte schneller sein, weil du im zweiten Beispiel für jeden Durchlauf einen Aufruf von end() hast (aber gute Compiler optimieren diesen Aufruf durch inline-Funktionen - da fällt der ZUsatzaufwand dann wieder weg).

    Ok, danke. Sowas habe ich mir schon fast gedacht 😛


Anmelden zum Antworten