Problem bei der Ausgabe (Dynamische Speicherverwaltung)



  • brauch ich das dann nicht so?

    (*Personen[i]).Name;
    

    oder so ähnlich?



  • Oder so (du willst ja bestimmt den ganzen Namen):

    getline(cin, (*(Personen+x)).Name);
    //getline(cin, (Personen+x)->Name);
    

    EDIT: Pellaeons Lösung geht auch, da man Pointer wie Arrays behandeln kann, und umgekehrt.
    EDIT2: Klammern einfügt



  • hab das mit der 1. lösung ausprobiert. ausgegeben wird alles richtig, nur anschließend bekomm ich ne fehlermeldung:

    Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)



  • der operator [] bei Zeigern bewirkt, dass automatisch die entsprechende Stelle im Feld adressiert wird UND das der Zeiger dereferenziert wird.

    Personen[i].Name entspricht (Personen + i)->Name oder (*(Personen + i)).Name

    Such dir aus was dir am besten gefällt^^



  • Der g++ macht keine Schwierigkeiten:

    #include <iostream>
    #include <cstdlib>
    #include <string>
    
    using namespace std;
    
    struct Verwaltung {
      string Name;
      int Nummer;
    };
    
    int main() {    
        Verwaltung *Personen=0;
    
        int n=0;
    
        cout << "Wie viele Datensaetze wollen Sie eingeben?\t";
        cin >> n;
        while (getchar()!='\n');
    
        Personen=new Verwaltung[n];
        for (int x=0; x<n; x++)
        {    cout << "\nName, Person " << x << ":\t\t";
            getline(cin, (Personen+x)->Name);
            cout << "Nummer, Person " << x << ":\t";
            cin >> (Personen+x)->Nummer;
            while (getchar()!='\n');
        }
    
        for (int x=0; x<n; x++)
        {    cout << "\n\nName, Person " << x << ":\t\t";
            cout << (Personen+x)->Name;
            cout << "\nNummer, Person " << x << ":\t";
            cout << (Personen+x)->Nummer;
        }
    
        delete [] Personen;
    
        getchar();
        return 0;
    }
    


  • GPC schrieb:

    Oder so (du willst ja bestimmt den ganzen Namen):

    getline(cin, *(Personen+x).Name);
    //getline(cin, (Personen+x)->Name);
    

    EDIT: Pellaeons Lösung geht auch, da man Pointer wie Arrays behandeln kann, und umgekehrt.

    ich seh grad: das geht schief. der "." hat ne höhere Priorität als der * also macht der doch *((Personen+x).Name).



  • Pellaeon schrieb:

    der operator [] bei Zeigern bewirkt, dass automatisch die entsprechende Stelle im Feld adressiert wird UND das der Zeiger dereferenziert wird.

    Personen[i].Name entspricht (Personen + i)->Name oder (*(Personen + i)).Name

    Such dir aus was dir am besten gefällt^^

    Wobei man bei Zeigern aus stilistischen Gründen zu -> raten sollte, v.a. da somit offensichtlicher wird, dass mit einem Zeiger gearbeitet wird.

    Pellaeon schrieb:

    GPC schrieb:

    Oder so (du willst ja bestimmt den ganzen Namen):

    getline(cin, *(Personen+x).Name);
    //getline(cin, (Personen+x)->Name);
    

    EDIT: Pellaeons Lösung geht auch, da man Pointer wie Arrays behandeln kann, und umgekehrt.

    ich seh grad: das geht schief. der "." hat ne höhere Priorität als der * also macht der doch *((Personen+x).Name).

    Eh jup, einmal Klammern bitte :xmas2:



  • und woran liegt das jetzt mit der fehlermeldung?

    habe auch

    (Personen + i)->Name

    ausprobiert, aber wie erwartet, hat das nix an der fehlermeldung geändert, die nach der ausgabe kommt.



  • Geh mal mit dem Debugger durch und schaue, wo der Fehler genau auftritt bei welcher Stelle



  • hab ich schon. aber genau am ende wird die meldung angezeigt.



  • tu mal das getch zu testzwecken rausu nd schau ob es dann geht. Der Code sieht eigentlich mit der Änderung sauber aus, mal abgesehen vom fehlenden delete[] natürlich



  • es lag daran, dass ich bereits das delete mit dazu genommen hab, da aber wohl n fehler drin habe.

    habe den delete befehl in die letzte for-schleife gepackt, aber was stimmt denn an der programmierung nicht, hab schon alles ausprobiert, ohne index, mit index, etc.

    for (int x=0; x<n; x++)
    	{	cout << "\n\nName, Person " << x << ":\t\t";
    		cout << (Personen + x)->Name ;
    		cout << "\nNummer, Person " << x << ":\t";
    		cout << (Personen + x)->Nummer ;
    		delete Verwaltung[x];
    	}
    


  • sarah1986 schrieb:

    delete Verwaltung[x];
    

    Die anweisung als solche ist schon unsinnig (sag blos, das hat dein Compiler geschluckt) - 'Verwaltung' ist der Typ. Du mußt deine Variable löschen und zwar als ganzes:

    for(int x=0; x<n; x++)
    {
      //Ausgaben
    }
    delete[] Personen;
    


  • DA liegt der fehler groß groß^^ 🤡

    Du hast mit new[] ein Feld dynamisch angelegt, dieses kannst du nun auch nur wieder als ganzes mit delete[]freigeben

    new <-> delete
    new[] <-> delete[]

    Also mache das

    delete[] Personen;
    

    nachdem zu das Feld nicht mehr benötigst, ergo nach der zweiten for-Schleife



  • so ähnlich hatte ich es auch, nur die eckigen klammern hinter dem personen... das ging net. aber so läufts hoffentlich. tausend dank



  • gibt es die möglichkeit mein programm so zu erweitern, dass ich die abfrage zuvor, wieviele datensätze ich anlegen will, weglasse, und durch irgendne bedingung dann aufgehört wird, wie beispielsweise ein ausrufezeichen.



  • Ja, allerdings wird die Speicherverwaltung dann schwieriger (weil du vorher wissen mußt, wieviel Platz du brauchst - da müsstest du den belegten Platz in regelmäßigen Abständen reorganisieren). Oder du könntest umsteigen auf STL-Container (vector oder deque).



  • da reichen meine bisherigen kenntnisse nicht aus, dann lass ich es dabei, trotzdem vielen dank



  • GPC schrieb:

    Oder so (du willst ja bestimmt den ganzen Namen):

    getline(cin, (*(Personen+x)).Name);
    //getline(cin, (Personen+x)->Name);
    

    EDIT: Pellaeons Lösung geht auch, da man Pointer wie Arrays behandeln kann, und umgekehrt.
    EDIT2: Klammern einfügt

    habe mich jetzt nochmal an das prog gesetzt, und versuche alles zu verstehen. was bewirkt dieses +x genau? Muss ich das unbedingt benutzen?

    Dann habe ich noch ne Frage:
    In der Berufsschule haben wir ein Aufgabenblatt zur Dyn. Speicherverwaltung bekommen. (Verwaltung von Artikeln) Dort steht:

    Als Datenstruktur soll ein 1-dimensionales Array mit Pointern vom Typ T_Artikel gewählt werden, was somit einer halbdynamischen Datenstruktur eintspricht: das Pointer-Array ist statisch, die eigentlichen Artikeldaten werden dynamisch angelegt.

    Was ist damit gemeint? - Ist das das gleiche, wie ich bei meinem Prog verwendet habe oder wieder etwas anderes?



  • also das "+ x" dort hat mit Zeigeraritkemtik zu tun.

    "Personen" ist dein Feld. Bei Feldern ist der Name ein Zeiger auf das erste Element im Feld, also die 0.te Stelle sozusagen.
    Bei Feldern liegen die Elemente zusammenhängend hintereinander im Speicher, deswegen ja ein Feld 🙂
    Wenn du jetzt auf das zweite Element zugreifen willst, musst du dich im Feld weiter bewegen. Ein int ist z.B. normalerweise momentan 4 Byte groß. Du müsstes dich also um 4 Adressen weiter bewegen von der Startadresse aus.
    C++ ist jedoch clever, jetzt kommt nämlich die Zeigerarithmetik ins Spiel.
    Wenn du einen Zeiger + 1 machst, springt er nicht einfach ein Byte weiter, sonder es wird nachgeschaut, von welchem Typ der Zeiger ist und dann wird eine Variable weiter gesprungen. Also am Beispiel hier der erkennt "aha ich zeige auf ein int, int ist 4 Byte groß, also muss ich bei + 1 4 Byte weiter gehen im Feld.

    Also sorgt die Zeile (Personen + x) das er die Adresse des x.ten Elements berechnet. Und wenn du nun die Adresse des x.ten Elements hast, kannst du damit arbeiten.

    Zu deiner 2. Frage:

    Du sollst ein Array von Pointern machen, also

    T_Artikel* zeigerFeld[100];
    

    In der Aufgabe steht statisch, also ohne new machen udn einfach nen festen wert abgeben.


Anmelden zum Antworten