Zweidimensionales Array erstellen (mit malloc)



  • Nein, auf Zeile 18.



  • Big Brother schrieb:

    Metalmind schrieb:

    ich bin mir relativ sicher dass der Fehler in Zeile 18 sitzt

    Das kommt darauf an wie du dich entschieden hast, dein Array zu erzeugen und die Elemente darin zu adressieren.
    Die Adressierung der Elemente kann prinzipiell so

    array[zeile][spalte]
    

    oder so

    array[y*spaltenbreite+x];
    

    aussehen.

    Ich hatte das jetzt so verstanden, dass in Zeile 18
    Bezeichnung[100][20];
    und
    Bezeichnung2 = (char*) malloc(laenge*20*sizeof(char));
    verglichen werden, die nach anderem Schema erzeugt werden, was nicht funktioniert.
    Habe ich mich da geirrt?


  • Mod

    Verglichen? Nein, da wird das eine in das andere kopiert.

    Dein Problem ist, dass du Bezeichner und Bezeichner2 auf unterschiedliche Weise erzeugt hast. Na gut, eigentlich ist das kein Problem. Aber du benutzt sie beide gleich. Bei Bezeichner hast du dem Compiler mit [100][20] gesagt, dass du 100 mal 20 Elemente haben willst. Bei Bezeichner2 hast du gesagt, dass du einmal 2000 Elemente haben willst. Daher bezieht sich Bezeichner[i] auf das insgesamt i*20-te Element. Bezeichner2[i] hingegen ist wirklich nur das i-te Element, weil der Compiler keine Ahnung hat, dass du dir die 2000 Elemente als 100*20 vorstellst. Das musst du ihm schon irgendwie klarmachen, dass du mit Bezeichner2[i] eigentlich das i*20-te Element meinst.

    P.S.: Kleiner Tipp: Die Lösung ist nicht schwer, ich hab's quasi schon hingeschrieben. Ich will nur, dass du nochmal drüber nachdenkst, damit du es beim nächsten Mal auch alleine hinbekommst.

    :hoppschwiiz:



  • Ich doktore dadran jetzt einige Zeit rum und habe (glaube ich) zwei Lösungen gefunden:
    entweder erzeuge ich das Array auf dieselbe Art, auf die mein "Grundarray" erstellt wurde, wie vorher zuwähnt:

    Für int[5][3]
    int **myPtr = malloc(5*sizeof(int*)); // erste Dimension
    myPtr[0] = malloc(3sizeof(int));
    myPtr[1] = malloc(3
    sizeof(int));
    myPtr[2] = malloc(3sizeof(int));
    myPtr[3] = malloc(3
    sizeof(int));
    myPtr[4] = malloc(3*sizeof(int));

    Oder ich finde einen Weg das 2000er Feld in 100*20er Felder aufzuteilen.
    Soweit richtig?



  • Ja.
    Etwas eleganter wäre noch
    int **myPtr = calloc(5,sizeof(int*));



  • Wäre das dann:

    char **Bezeichnung2 = calloc(laenge,sizeof(char*));
    for(i=0;i<laenge;i++)
    {
    Bezeichnung2[laenge] = malloc(20*sizeof(char));
    }
    

    Um 100 Elemente mit 20 Zeichen als Ersatz für

    Bezeichnung2 = (char*) malloc(laenge*20*sizeof(char));
    

    zu erstellen?



  • bzw laenge Elemente



  • Scheinbar mache ich noch irgendwas verkehrt, ich habe nun meinen Code durch:

    char **Bezeichnung2 = calloc(laenge,sizeof(char*));
    for(i=0;i<laenge;i++)
    {
    Bezeichnung2[laenge] = malloc(20*sizeof(char));
    }
    for(i=0;i<laenge;i++){  
        strcpy(Bezeichnung2[i],Bezeichnung[i]);
    }
    

    ersetzt, nun stürzt das Programm bei der Ausgabe ab



  • Wutz schrieb:

    Ja.
    Etwas eleganter wäre noch
    int **myPtr = calloc(5,sizeof(int*));

    Dem kann ich keine Eleganz abgewinnen, bestenfalls Überfluss, denn die Zeiger werden anschließend sofort zugewiesen. Wozu also unnötigerweise doppelte Initialisierung?

    Metalmind01 schrieb:

    Scheinbar mache ich noch irgendwas verkehrt

    Schreib doch mal Bezeichnung2[i] anstatt Bezeichnung2[laenge].



  • Okay, sorry, das war einfach dumm...

    Nun sieht das ganze so aus:

    char **Bezeichnung2 = malloc(laenge*sizeof(char*)); 
    for(i=0;i<laenge;i++)
        {
            Bezeichnung2[i] = malloc(100*sizeof(char));
        }
    for(i=0;i<laenge;i++){  
        strcpy(Bezeichnung2[i],Bezeichnung[i]);
    }
    


  • Nun kommt bei der Ausgabe etwas merkwürdiges raus, zwei komische, immer unterschiedliche Zeichen gefolgt von ")".
    Was haltet ihr denn nun von meinem Code?



  • Metalmind01 schrieb:

    Nun kommt bei der Ausgabe etwas merkwürdiges raus, zwei komische, immer unterschiedliche Zeichen gefolgt von ")".
    Was haltet ihr denn nun von meinem Code?

    das da nen error driennen ist noch irgenwo



  • Okay, ich gehe das alles mal Zeile für Zeile hier durch, vielleicht fällt euch ja der Denkfehler auf den ich übersehen habe...

    char* *Bezeichnung2 = malloc(laenge*sizeof(char*));
    

    char* *Bezeichnung2 müsste eigendlich dasselbe sein wie char **Bezeichnung oder?
    hier wird ie erste Dimension des Arrays erstellt, mit der Anzahl laenge und von der größe char*, was mit dem char aus Bezeichnung kompatibel sein müsste.

    for(i=0;i<laenge;i++)
    {
    Bezeichnung2[i] = malloc(20*sizeof(char*));
    }
    

    Die zweite Dimension wird für Bezeichnung2 erzeugt, jeweils 20 Zeichen werden für einen String reserviert, auch diese Dimension hat die Größe char*.

    for(i=0;i<laenge;i++){  
    		strcpy(Bezeichnung2[i],Bezeichnung[i]);
        }
    

    Am Ende wird laenge mal der Inhalt von Bezeichnung[100][20] (in char) in ein jetzt eigendlich identisches Zeigerarray des Typs char* *Bezeichnung[laenge][20] kopiert. Der Index [i] beschreibt die erste Dimension und schreibt so laenge mal Strings der maximalen Größe [20] in die Felder.
    Soweit ist doch eigendlich alles richtig und müsste funktionieren, oder?

    Gruß
    Metalmind


  • Mod

    Metalmind01 schrieb:

    Okay, ich gehe das alles mal Zeile für Zeile hier durch, vielleicht fällt euch ja der Denkfehler auf den ich übersehen habe...

    char* *Bezeichnung2 = malloc(laenge*sizeof(char*));
    

    char* *Bezeichnung2 müsste eigendlich dasselbe sein wie char **Bezeichnung oder?
    hier wird ie erste Dimension des Arrays erstellt, mit der Anzahl laenge und von der größe char*, was mit dem char aus Bezeichnung kompatibel sein müsste.

    Ja. Wo die Sternchen stehen ist total egal.

    for(i=0;i<laenge;i++)
    {
    Bezeichnung2[i] = malloc(20*sizeof(char*));
    }
    

    Die zweite Dimension wird für Bezeichnung2 erzeugt, jeweils 20 Zeichen werden für einen String reserviert, auch diese Dimension hat die Größe char*.

    Knartsch! Wie kommst du auf char* als Größe? Ich meine: Ja, da steht sizeof(char*), aber das ist falsch!

    Auf der linken Seite steht ja ein char* (Weil Bezeichnung2 ein char** ist und einmal dereferenziert wird). Und worauf sollte ein char* wohl zeigen?



  • Metalmind01 schrieb:

    Okay, ich gehe das alles mal Zeile für Zeile hier durch,

    nein. du baust nen neuen fehler ein.

    malloc(20*sizeof(char*));
    

    damit reservierst du mehr speicher, als du willst (sizeof(char*) > sizeof(char)).
    muss heißen

    malloc(20*sizeof(char));
    

    es reicht auch

    malloc(20);
    

    weil sizeof(char) immer 1 ist.



  • Ich habe keinen neuen Fehler eingebaut, aber jetzt einen alten berichtigt 😃
    Warum da so ein Zeichenmatsch rauskommt ist mir aber immernoch schleierhaft, eigendlich sollten die Daten nun ordnungsgemäß kopiert werden...oder nicht?


  • Mod

    Metalmind01 schrieb:

    Ich habe keinen neuen Fehler eingebaut, aber jetzt einen alten berichtigt 😃
    Warum da so ein Zeichenmatsch rauskommt ist mir aber immernoch schleierhaft, eigendlich sollten die Daten nun ordnungsgemäß kopiert werden...oder nicht?

    Die Kopierroutine funktioniert, keine Angst. Aber du machst abwechselnd Fehler beim Speicher reservieren und bei der Angabe des Ortes wo die Zeichen hinkopiert werden sollen und bei der Angabe welche Zeichen ausgegeben werden sollen.



  • Die Kopierroutine funktioniert, keine Angst.

    Also ist dieser Teil

    for(i=0;i<laenge;i++)
    {  
        strcpy(Bezeichnung2[i],Bezeichnung[i]);
    }
    

    richtig

    Aber du machst abwechselnd Fehler beim Speicher reservieren

    char* *Bezeichnung2 = malloc(laenge*sizeof(char*)); 
    for(i=0;i<laenge;i++)
    {
        Bezeichnung2[i] = malloc(20);
    }
    

    Da müssten doch nun eigendlich alle Fehler behoben sein

    und bei der Angabe des Ortes wo die Zeichen hinkopiert werden sollen

    Das müsste dann ja diese Zeile sein

    strcpy(Bezeichnung2[i],Bezeichnung[i]);
    

    und bei der Angabe welche Zeichen ausgegeben werden sollen.

    Das ist dann dieser Teil:

    for (i=0;i<laenge;i++)
    {
        printf("%s\n",&Bezeichnung2[i]);
    }
    

    der meiner Meinung nach richtig ist



  • soweit richtig?


  • Mod

    Metalmind01 schrieb:

    soweit richtig?

    Kommt denn das richtige raus?

    Der letzte Teil müsste falsch sein. Der Adressoperator hat da nichts zu suchen.


Anmelden zum Antworten