malloc(sizeof(int)) vs malloc(sizeof(int *)) vs (int *)malloc(sizeof(int))

Lesezeit: 3 Minuten

Benutzer-Avatar
Rajawal

Ich erkenne an, dass alle drei eine unterschiedliche Bedeutung haben. Aber ich verstehe nicht, auf welche konkreten Fälle dies jeweils zutreffen würde. Kann jemand ein Beispiel für jede davon geben? Vielen Dank.

       malloc(sizeof(int))
       malloc(sizeof(int *))
(int *)malloc(sizeof(int))

Benutzer-Avatar
Gort der Roboter

malloc(sizeof(int)) bedeutet, dass Sie Speicherplatz außerhalb des Heaps zuweisen, um eine zu speichern int. Sie reservieren so viele Bytes wie ein int erfordert. Dies gibt einen Wert zurück, auf den Sie umwandeln sollten int *. (Ein Zeiger auf eine int.) Wie einige angemerkt haben, besteht die typische Praxis in C darin, dies durch implizites Casting erledigen zu lassen.

malloc(sizeof(int*)) bedeutet, dass Sie Speicherplatz außerhalb des Heaps zuweisen, um einen Zeiger auf ein zu speichern int. Sie reservieren so viele Bytes, wie ein Zeiger benötigt. Dies gibt einen Wert zurück, den Sie in ein umwandeln sollten int **. (Ein Zeiger auf einen Zeiger auf eine int.)

(int *)malloc(sizeof(int)) ist genau das gleiche wie der erste Aufruf, aber das Ergebnis wird explizit in einen Zeiger auf an umgewandelt int.

Beachten Sie, dass auf vielen Architekturen an int hat die gleiche Größe wie ein Zeiger, daher scheinen diese (fälschlicherweise) alle dasselbe zu sein. Mit anderen Worten, Sie können versehentlich das Falsche tun und der resultierende Code funktioniert trotzdem.

  • +1 für den letzten Absatz – aber meiner Erfahrung nach machen viele C-Programmierer “absichtlich” das Falsche und es funktioniert, also machen sie weiter …

    – mattnz

    5. März 2013 um 8:32 Uhr

  • RE erster Absatz: In C argumentieren viele Leute, dass Sie es nicht umwandeln sollten (es gibt eine implizite Konvertierung von void * zu jedem Zeigertyp in C, damit es funktioniert). Siehe stackoverflow.com/q/605845/395760

    Benutzer395760

    5. März 2013 um 14:31 Uhr

  • @StevenBurnap Ich vermute, du meinst tatsächlich “benutzen”, wo du “besetzen” sagst. Es gibt eine implizite Konvertierung von void* in einen anderen Datenzeigertyp (ich erinnere mich jedoch nicht, ob der Standard besagt, dass Sie einen void* sicher in einen Funktionszeiger umwandeln können).

    – Vatine

    20. März 2013 um 15:09 Uhr


Benutzer-Avatar
Wildpässer

Das idiotensicherste Syntaxmuster ist:

 int *p;
 p = malloc (cnt * sizeof *p);

Diese Syntax zwingt Sie nicht, den Code zu ändern, wenn sich der Typ (und oder die Größe …) von *p ändert, z. B. in

 struct mysstruct *q;
 q = malloc (cnt * sizeof *q);

Das vermeidet Probleme wie

struct mysstruct *z;
z = malloc (cnt * sizeof(struct hisstruct)); // Auch!

plus: die sizeof expr Form ist auch kürzer.


UPDATE: um die Korrektheit zu demonstrieren p = malloc(CNT * sizeof *p) dieses Testprogramm:

#include <stdio.h>
#include <stdlib.h>

struct mystruct {
        int i;
        char s[14];
        };
int main(void)
{
struct mystruct *p;
size_t siz;

siz = sizeof p;
printf("Sizeof p := %zu\n", siz);

siz = sizeof *p;
printf("Sizeof *p := %zu\n", siz);

printf("Allocating %zu (%u structs, each of size %zu) bytes to be assigned to p...\n"
        , 10u * sizeof *p
        , 10u, sizeof *p
        );
p = malloc(10 * sizeof *p);

return 0;
}

Welche Ausgänge hier:

Sizeof p := 8
Sizeof *p := 20
Allocating 200 (10 structs, each of size 20) bytes to be assigned to p...

  • Das Muster ist es nicht malloc (cnt * sizeof *p)aber wie die akzeptierte Antwort richtig vermerkt hat, sizeof p. Dasselbe gilt für q/*q. Ansonsten braucht man int **p um das Ergebnis richtig zu halten.

    – Verschränkte Schleifen

    2. Juni 2015 um 20:00 Uhr

  • Ich verstehe deine Frage nicht. Type *t; t = malloc(CNT * sizeof *t); ist stets richtig, die anderen Varianten sind manchmal Rechts.

    – Wildpässer

    2. Juni 2015 um 21:32 Uhr


  • @snd Du liegst falsch; Ich habe meiner Antwort einen Ausschnitt hinzugefügt.

    – Wildpässer

    3. Juni 2015 um 14:28 Uhr


  • Ich nicht beabsichtigen Um Speicher für einen Zeiger (das wäre nutzlos) oder für 10 Zeiger zuzuweisen, beabsichtige ich, Speicher für 10 Strukturen zuzuweisen. Und es ist nicht “Nicht-Standard-Syntax” (was auch immer das ist)

    – Wildpässer

    3. Juni 2015 um 18:36 Uhr

  • Das habe ich im dritten Teil erklärt (der mit dem // Auch!) Der Punkt, den ich zu machen versuche, ist das malloc(10 * sizeof(struct mystruct)) (Übrigens: diese Syntax braucht die Klammern) ist fehleranfälliger (weil struct mystruct sollte dem entsprechen tatsächlich gewünschten Typ) Wenn Sie eine Änderung vornehmen: Sie müssen beide ändern.

    – Wildpässer

    3. Juni 2015 um 18:58 Uhr


1329500cookie-checkmalloc(sizeof(int)) vs malloc(sizeof(int *)) vs (int *)malloc(sizeof(int))

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy