Malloc ein 2D-Array in C [duplicate]

Lesezeit: 5 Minuten

Benutzeravatar von Ninazzo
Ninazzo

Jedes Mal, wenn ich den Speicher für ein 2D-Array zuweise, erstelle ich zuerst ein Array von int** und dann mit einem for weise ich den Speicher für jedes Element zu.

Zum Beispiel:

int ** arr = malloc(N*sizeof(int *));
for(i=0; i< N; i++) arr[i] = malloc(M*sizeof(int));

Wäre nicht möglich, den Speicher wie folgt zuzuweisen:

int ** arr = malloc(N*sizeof(int[M]));

oder

int ** arr = malloc(sizeof(int[N][M]));

um das zu vermeiden for?

  • Benutzt du C oder C++?

    – NathanOliver

    27. April 2016 um 13:01 Uhr

  • Sie könnten Ihre eigene Funktion schreiben, die alles Notwendige dafür enthält. Abgesehen davon gibt es keine Syntaxtricks, die dies ermöglichen würden.

    – Zwielichtiger Programmierer

    27. April 2016 um 13:04 Uhr


  • Siehe auch diese Antwort.

    – Johannes Bode

    27. April 2016 um 14:26 Uhr

so was : int (*arr)[M] = malloc(sizeof(int[N][M]));

arr ist ein Zeiger auf int[M].

benutze wie arr[0][M-1];

und free(arr);

  • Noch besser – int (*arr)[M] = malloc( sizeof *arr * N );. Auf diese Weise müssen Sie die nicht ändern sizeof Ausdruck, wenn der Typ von arr jemals ändert.

    – Johannes Bode

    27. April 2016 um 14:19 Uhr

  • @JohnBode siehe diese Antwort

    – BLUEPIXY

    27. April 2016 um 14:33 Uhr

  • @JohnBode In diesem Beitrag bin ich einer ähnlichen Meinung wie du. Es sollte jedoch vermieden werden, da es im Standard keine Garantie für solche Operationen gibt.

    – BLUEPIXY

    27. April 2016 um 16:27 Uhr

  • Und dann ist da noch diese Sprache aus 5.1.2.3/4: „In der abstrakten Maschine werden alle Ausdrücke so ausgewertet, wie es die Semantik vorgibt. Eine tatsächliche Implementierung muss einen Teil eines Ausdrucks nicht auswerten, wenn daraus abgeleitet werden kann, dass sein Wert nicht verwendet wird und dass keine erforderlichen Nebeneffekte erzeugt werden (einschließlich aller, die durch den Aufruf einer Funktion oder den Zugriff auf ein flüchtiges Objekt verursacht werden).” Ich denke, das gibt uns einen Ausweg für die Verwendung sizeof auf einem Zeiger auf ein VLA.

    – Johannes Bode

    27. April 2016 um 16:35 Uhr


  • @BLUEPIXY Das funktioniert also nicht, wenn M eine Variable ist?

    – Anchith Acharya

    28. März 2020 um 11:41 Uhr

Benutzeravatar von Fluter
flattern

int ** arr = malloc(N*sizeof(int[M]));

ist falscher C-Code, wenn Sie ihn durch einmaliges Zuweisen simulieren
int *arr = malloc(N*M*sizeof(int));

und greifen Sie darauf zu
arr[i*M + j],
dies ist ein Analogon zu arr[I][j] in deinem ersten Fall.

  • @Olaf Beruhige dich, es gibt kein 2D-Array, das du mit C haben kannst, das OP möchte einmal einen Puffer zuweisen, der NxM Ints enthält.

    – flattern

    27. April 2016 um 13:06 Uhr


  • Außerdem ist es überhaupt nicht “veraltet”, es ist etwas, das Sie heute sehen. Es hängt alles von Ihrem Anwendungsfall ab. Es ist seltsam, dass Sie eine Art von Code doch als “obsolet” deklarieren können.

    – flattern

    27. April 2016 um 13:07 Uhr

  • Ich habe nur gefragt, ob es einen Weg gibt wie das, das habe ich nie gesagt das war der Weg.

    – Ninazzo

    27. April 2016 um 13:11 Uhr

  • @fluter: Das kannst du sehr wohl! Siehe meine Antwort. Und ja, es ist obsolet. Es gibt nur zu viele Programmierer, die denken, dass es in C keine mehrdimensionalen Arrays gibt. Aber nur weil “wir es die ganze Zeit so gemacht haben”, heißt das nicht, dass es der richtige Weg ist. Tatsächlich spricht in Ihrer Version kein einziger Vorteil, sondern vieles dagegen, zB: fehleranfällig, schwerer verständlich, Sie müssen die Innenlänge selbst nachzeichnen.

    – zu ehrlich für diese Seite

    27. April 2016 um 13:15 Uhr


  • Oh, und Entschuldigung für die heftige Reaktion. Es ist einfach zu viel Verwirrung über Arrays und Zeiger. Und zu viele Programmierer haben Angst vor der Verwendung komplexer Arrays, obwohl es ziemlich einfach wird, sobald Sie das Konzept verstanden haben (mit Qualifizierern wird es jedoch noch schlimmer).

    – zu ehrlich für diese Seite

    27. April 2016 um 13:22 Uhr


zu ehrlich für den Benutzer-Avatar dieser Seite
zu ehrlich für diese Seite

Sie haben einen “Zeiger zu Zeiger”. Das kann kein 2D-Array darstellen.

Die korrekte Deklaration eines Zeigers auf ein 2D-Array ist

// number of elements in one row
#define COLS 10

// number of rows
#define ROWS 20

int (*array)[COLS];   // mind the parenthesis!

Das macht array a Zeiger auf Array von COLS ints. Der Typ ist `int[COLS]

, übrigens. aber Sie brauchen den Typ nicht, siehe unten.

array = malloc(sizeof(*array) * ROWS);   // COLS is in the `sizeof`

array = malloc(sizeof(int[ROWS][COLS])); // explicit 2D array notation

Um das Array zuzuweisen, sollten Sie dann die Standardzuweisung für ein 1D-Array verwenden: array Welche Variante zu verwenden ist, ist der persönliche Stil. Während die erste keine Redundanz enthält (erwägen Sie, die Deklaration von zu ändern INNER benutzen COLS Anstatt von floatoder der Elementtyp zu array). Die zweite ist auf den ersten Blick übersichtlicher, aber fehleranfälliger bei der Änderung der Deklaration von

. freeZu

free(array);

  • :

    Mich würde interessieren, was der Einwand des Downvoters war.

    – Michael Petsch

  • 28. April 2016 um 13:16 Uhr

    @MichaelPetch: Ich auch. Aber Sie können nicht mit <(naja, Sie haben vielleicht eine Idee, was ich hier schreiben würde)> argumentieren.

    – zu ehrlich für diese Seite

  • array = int (*)[COLS] malloc(ROWS*COLS*sizeof(int)) 28. April 2016 um 13:19 Uhr kann

    intuitiver sein

    – rfabbri


  • 29. April 2019 um 21:35 Uhr

    @rfabbri Das ist weniger intuitiv als die zweite Variante, die ich vorschlage. Zusätzlich garantiert die erste vorgeschlagene Version auch, dass der innere Index immer konsistent zum Zeigertyp ist. Dies gilt nicht für die zweite und Ihre Variante. Abschließend: nie ´void *´ in C typisieren! Dies ist eine der Dummheiten einiger Programmierstile. Bitte beachten Sie, dass dies in C++ anders ist, aber das ist eine andere Sprache, die hier nicht behandelt wird.

    – zu ehrlich für diese Seite

1433210cookie-checkMalloc ein 2D-Array in C [duplicate]

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

Privacy policy