Array größe zuweisen - Problem



  • Hallo,

    ich möchte einem Array die größe zusweisen. Nur irgendetwas läuft schief.

    int a;
    
    printf("Wie gross soll das Array sein?: ");
       scanf("%d", &a);
       int *arr=(int *)malloc(a*sizeof(int));
    

    da das Programm aber nicht macht was es soll und der Fehler irgendwo in der Größenzusweisung des Arrays liegt, habe ich mir die Größe ausgeben lassen

    int len = sizeof(arr)/sizeof(int);
    

    Hier erhalte ich als Wert für len=1 (egal welchen Wert ich oben bei scanf eingebe)

    wenn ich die größe des Arrays folgendermaßen festlege, läuft das Programm ohne Problem, nur hat unser Prof gesagt, dass wir diese Methode auf keinen Fall nutzen dürfen

    printf("Wie gross soll das Array sein?: ");
       scanf("%d", &a);
       int arr[a];
    

    Bei dieser Methode wird dann auch jedesmal, wenn ich mit:

    int len = sizeof(arr)/sizeof(int);
    

    die größe ausgebe, die Korrekte Zahl ausgegeben.

    Was mache ich bei der oberen Zuweisung mit malloc falsch?

    Danke



  • Du benutzt im 2. Fall VLA, also variable length array, also ein Array.
    Nur Deppen benutzen VLA.
    Im 1. Fall benutzt du überhaupt kein Array, sondern einen Zeiger (auf dynamischen Speicher).
    Nur Deppen benutzen einen malloc-Cast.
    Nur Deppen behandeln Zeiger und Array gleich, obwohl ich zugebe, dass dies 99% aller Anfänger (und >80% aller "Fortgeschrittenen") so machen, weil es ihnen so gelehrt wird oder sie nicht lesen/begreifen können; es also ein Fehler ist, den neben dir viele andere machen; sie reden von Array meinen aber Zeiger u.u.



  • Dass man den 2. Fall nicht nutzen soll weiss ich. Aber nicht warum bei mir der Speicher für das Array nicht richtig reserviert wird.

    auf http://www.c-howto.de/tutorial-arrays-felder-speicherverwaltung.html heisst es

    int size=0;
    	int *array;
    
    	printf("Array-Groesse eingeben: ");
    	scanf("%d", &size);
    
    	// Speicher reservieren
    	array = (int *) malloc(size * sizeof(int));
    

    bei mir sieht es doch genauso aus aber ich bekomme immer nur Speicherplatz für 1ne int Zahl.



  • bei mir sieht es doch genauso aus aber ich bekomme immer nur Speicherplatz für 1ne int Zahl.

    Ne, passt schon.

    Wenn du einen Pointer int *ptr deklarierst gibt sizeof(ptr) die Größe des Pointers zurück, auch wenn du "hinter" dem Pointer ein arrayartiges Konstrukt hast (was aber eben kein Array ist, das wäre mit den eckigen Klammern wodurch auch sizeof() "funktioniert").

    Nur Deppen benutzen VLA.

    Lese ich jetzt zum n-ten Mal hier, hat irgendwo mal jemand erklärt warum?

    Nur Deppen benutzen einen malloc-Cast.

    Warum?



  • bratkartoffel schrieb:

    Nur Deppen benutzen einen malloc-Cast.

    Warum?

    malloc gibt void* zurück und void* ist implizit in [cv] Irgendwas* konvertierbar. Der Cast ist also überflüssig.

    Wobei ich das "nur Deppen machen xyz" ziemlich scheisse finde. Oder ist das hier im C Forum (wo ich zugegebenermassen kaum mitlese) so üblich?



  • hustbaer schrieb:

    Der Cast ist also überflüssig.

    Ok, "nur" überflüssig, sonst nichts.

    Wobei ich das "nur Deppen machen xyz" ziemlich scheisse finde.

    Ja, besonders ohne weitere Erklärung oder einem Link warum!

    Oder ist das hier im C Forum (wo ich zugegebenermassen kaum mitlese) so üblich?

    Ich habe es jedenfalls schon öfters gelesen.



  • bratkartoffel schrieb:

    Ok, "nur" überflüssig, sonst nichts.

    Das ist kein "nur" 😉 Wenn man das hinschreibt heißt es, man weiß nicht, dass man das nicht braucht und warum, und das heißt, man beherrscht seine Programmiersprache eher oberflächlich.



  • Ich stolperte neulich über Folgendes:

    "Der Zeiger, den malloc oder calloc liefern, hat die korrekte Ausrichtung für das gewünschte Objekt, muß aber noch mit einer Umwandlungsoption in den richtigen Datentyp umgewandelt werden, zu Beispiel

    int *ip;
    ip = (int 😉 calloc(n, sizeof(int));"

    Quelle: K&R - Programmieren in C (Zweite Ausgabe)

    Wollte das nur mal anbringen und hoffe, dass mich jemand erhellen kann.



  • Mechanics schrieb:

    Das ist kein "nur" 😉

    Schon richtig, aber es hat keine Nachteile wie andere Casts die irgendwelche Kontrollen (und ggf. Warnungen) vom Compiler unterdrücken.

    Ich stolperte neulich über Folgendes: [...]

    Tatsächlich! Hier der englische Text, auch 2nd. ed.

    K&R schrieb:

    The pointer retourned by malloc or calloc has the proper alignment for the object in question, but it must be cast into the appropriate type as in

    int *ip;
    pi = (int *) calloc(n, sizeof(int));
    

    😮 😕



  • Früher, bzw. damals im letzten Jahrtausend, gab malloc einen char* zurück.

    Das war allerdings noch in den ersten Versionen von C.
    Da die zweite Ausgabe allerdings schon Ansi-C beschreibt, ist das dort ein Fehler.



  • "xyz machen nur Deppen" ist ein running Gag hier. Wie immer mit running Gags: verstehen nur Insider...

    Zu K&R und malloc() / calloc() und dem cast ihres Ergebnisses. Das wird schon in Kap. 6.5 erwähnt - als auch in 7.5.8.
    Ich habe Errata gefunden, die das korrigieren.
    Allerdings ist es mir nicht so wichtig "die richtigen offiziellen" Errata zum Buch gesucht zu haben.

    Dem OP sei noch gesagt: Die Allozierung die Du implementiert hast

    int a;
    
    printf("Wie gross soll das Array sein?: ");
    scanf("%d", &a);
    int *arr=(int *)malloc(a*sizeof(int));
    

    ist soweit korrekt. Wenn es trotzdem hakt, liegt das Problem woanders.



  • Furble Wurble schrieb:

    "xyz machen nur Deppen" ist ein running Gag hier. Wie immer mit running Gags: verstehen nur Insider...

    OK. Ich hab' das auch schon 1-2 mal hier gelesen, daher war ich mir nicht sicher.
    Ist aber irgendwie ein schlechter Running Gag, oder? Ich meine... wie du schon selbst schreibst verstehen das nur Insider, und was ein Neuling sich denkt wenn man ihm das schreibt kann man sich ja denken.

    Aber egal, hat sich erledigt - hab mir ne PS4 gekauft!



  • Wutz schrieb:

    Nur Deppen benutzen VLA.

    Das glaube ich nicht, Tim.



  • DirkB schrieb:

    Früher, bzw. damals im letzten Jahrtausend, gab malloc einen char* zurück.

    Das war allerdings noch in den ersten Versionen von C.
    Da die zweite Ausgabe allerdings schon Ansi-C beschreibt, ist das dort ein Fehler.

    Ach so, Danke für die Info.

    Dem OP sei noch gesagt: Die Allozierung die Du implementiert hast ist soweit korrekt.

    Ja und zum sizeof() siehe meine Antwort 17:13:55 07.06.2015.

    Ist aber irgendwie ein schlechter Running Gag, oder?

    imho ja mit gleicher Begründung wie hustbaer.



  • DirkB schrieb:

    Früher, bzw. damals im letzten Jahrtausend, gab malloc einen char* zurück.

    Das war allerdings noch in den ersten Versionen von C.
    Da die zweite Ausgabe allerdings schon Ansi-C beschreibt, ist das dort ein Fehler.

    Aha, womöglich wurde es aus der ersten Ausgabe übernommen!?
    Danke jedenfalls für die Erläuterung.



  • In dem Buch sind Fehler. In der deutschen und auch in der Originalausgabe.

    Einer der Autoren hatte auf seiner Webseite auch mal eine Errata Liste.
    Die Seite von Ritchie ist nicht mehr vorhanden und auf der Seite von Kernighan ist ein Dead-Link. 😞



  • Für K&R2 gibts Korrekturen, die enthalten auch das Problem mit dem (ab C89) unnötigen (und u.U. andere Compiler-Fehlermeldungen verdeckenden) Cast auf S.142:

    The remark about casting the return value of malloc ("the proper method is to declare ... then explicitly coerce") needs to be rewritten. The example is correct and works, but the advice is debatable in the context of the 1988-1989 ANSI/ISO standards. It's not necessary (given that coercion of void * to ALMOSTANYTYPE * is automatic), and possibly harmful if malloc, or a proxy for it, fails to be declared as returning void *. The explicit cast can cover up an unintended error. On the other hand, pre-ANSI, the cast was necessary, and it is in C++ also.
    Errata for The C Programming Language, Second Edition (Original, leider mittlerweile broken)
    Errata for The C Programming Language, Second Edition



  • 👍


Anmelden zum Antworten