Ordnen Sie Speicher 2d Array in Funktion C zu

Lesezeit: 5 Minuten

Benutzer-Avatar
serhii

Wie kann dynamischer Speicher für 2D-Array in Funktion zugewiesen werden? Ich habe es so versucht:

int main()
{
  int m=4,n=3;
  int** arr;
  allocate_mem(&arr,n,m);
}


void allocate_mem(int*** arr,int n, int m)
{
  *arr=(int**)malloc(n*sizeof(int*));
  for(int i=0;i<n;i++)
    *arr[i]=(int*)malloc(m*sizeof(int));
} 

Aber es funktioniert nicht.

  • mögliches Duplikat von Wie richte ich ein mehrdimensionales Array in C korrekt ein, greife darauf zu und befreie es?

    – Ludin

    25. Februar 2013 um 8:31 Uhr

Benutzer-Avatar
Grijesh Chauhan

Dein Code ist falsch bei *arr[i]=(int*)malloc(m*sizeof(int)); weil die Vorrang des [] Betreiber ist höher als die * Referenzoperator: Im Ausdruck *arr[i]Erste arr[i] wird dann ausgewertet * wird angewandt. Was Sie brauchen, ist das Gegenteil (dereference arrdann bewirb dich []).

Verwenden Sie Klammern wie folgt: (*arr)[i] um die Operatorpriorität zu überschreiben. Nun sollte Ihr Code so aussehen:

void allocate_mem(int*** arr, int n, int m)
{
  *arr = (int**)malloc(n*sizeof(int*));
  for(int i=0; i<n; i++)
    (*arr)[i] = (int*)malloc(m*sizeof(int));
} 

Um weiter zu verstehen, was im obigen Code passiert, lesen Sie diese Antwort.

Es ist wichtig, dass Sie dynamisch zugewiesenen Speicher immer explizit freigeben, wenn Sie damit fertig sind. Um den von der obigen Funktion zugewiesenen Speicher freizugeben, sollten Sie Folgendes tun:

void deallocate_mem(int*** arr, int n){
    for (int i = 0; i < n; i++)
        free((*arr)[i]);
    free(*arr); 
}

Darüber hinaus besteht eine bessere Möglichkeit zum Erstellen eines 2D-Arrays darin, zusammenhängenden Speicher mit einem einzigen zuzuweisen malloc() Funktionsaufruf wie folgt:

int* allocate_mem(int*** arr, int n, int m)
{
  *arr = (int**)malloc(n * sizeof(int*));
  int *arr_data = malloc( n * m * sizeof(int));
  for(int i=0; i<n; i++)
     (*arr)[i] = arr_data + i * m ;
  return arr_data; //free point
} 

Um diesen Speicher freizugeben:

void deallocate_mem(int*** arr, int* arr_data){
    free(arr_data);
    free(*arr);
}

Beachten Sie, dass bei der zweiten Technik malloc nur zweimal aufgerufen wird, und daher wird free beim Deallocation-Code nur zweimal aufgerufen, anstatt ihn in einer Schleife aufzurufen. Diese Technik sollte also besser sein.

  • @user2089491 Wenn Ihr Problem dadurch gelöst wurde, akzeptieren Sie diese Antwort als richtig, indem Sie links auf das “Häkchen” klicken.

    – Ludin

    25. Februar 2013 um 8:33 Uhr

Beachten Sie Folgendes: Nur eine einzige Zuweisung

int** allocate2D(int m, int n)
{
    int **a = (int **)malloc(m * sizeof(int *) + (m * n * sizeof(int)));

    int *mem = (int *)(a + m);

    for(int i = 0; i < m; i++)
    {
        a[i] = mem + (i * n);
    }

    return a;
}

Befreien:

free(a);

Wenn die Größe Ihres Arrays nicht geändert werden muss (naja, das können Sie, aber das wird etwas komplizierter), gibt es einen einfacheren/effizienteren Weg, 2D-Arrays in C zu erstellen.

Schauen Sie sich an http://c-faq.com/aryptr/dynmuldimary.html.

Die zweite Methode (für das Array namens array2) ist ziemlich einfach, weniger schmerzhaft (versuchen Sie, die Tests für den Rückgabewert von mallocs hinzuzufügen) und viel effizienter.

Ich habe es gerade für ein 200×100-Array bewertet, das 100000 Mal zugewiesen und freigegeben wurde:

  • Methode 1: 1,8 s
  • Methode 2: 47 ms

Und die Daten im Array werden zusammenhängender sein, was die Dinge beschleunigen kann (Sie erhalten möglicherweise einige effizientere Techniken zum Kopieren, Zurücksetzen … eines auf diese Weise zugewiesenen Arrays).

  • Ich stimme dir teilweise zu. Wenn Sie mit arbeiten riesig Arrays (mehrere hundert, sogar tausende von Mo) oder vielleicht in einigen eingeschränkten Systemen, ist diese Methode möglicherweise nicht geeignet, da Sie möglicherweise auf Probleme mit der Zuweisung großer Blöcke aus dem Heap stoßen (aber es besteht die Möglichkeit, dass Sie was auch immer vermasselt haben gewählte Methode). Aber in den meisten Fällen ist diese Methode ziemlich sicher und wirklich effizient.

    – Cyrille Faucheux

    26. März 2013 um 18:36 Uhr


Benutzer-Avatar
Smit Patel

Anstatt den Speicher in vielen verschiedenen Blöcken zuzuweisen, kann man diesen in einem aufeinanderfolgenden Speicherblock zuweisen. Mach Folgendes:

int** my2DAllocation(int rows,int columns)
{
   int i;
   int header= rows *sizeof(int *);
   int data=rows*cols*sizeof(int);
   int ** rowptr=(int **)malloc(header+data);
   if(rowptr==NULL)
   {
      return NULL:
   }
   int * buf=(int*)(rowptr+rows);
   for(i=0;i<rows;i++)
   {
      rowptr[i]=buf+i*cols;
   } 
   return rowptr;
}

Benutzer-Avatar
autistisch

Das ist eine unnötig komplizierte Art, Platz für ein Array zuzuweisen. Betrachten Sie diese Redewendung:

int main(void) {
    size_t m = 4, n = 3;
    int (*array)[m];
    array = malloc(n * sizeof *array);
    free(array);
}

  • 2d_array ist jedoch kein gültiger Bezeichner!

    – Antti Haapala – Слава Україні

    23. März 2019 um 13:03 Uhr

Benutzer-Avatar
Nanogehirne

Ich habe den folgenden Code zum Zuweisen von Speicher zu einem zweidimensionalen Array ausprobiert.

    #include<stdio.h>
    #include<malloc.h>
    void main(void)
    {
    int **p;//double pointer holding a 2d array
    int i,j;
    for(i=0;i<3;i++)
    {
    p=(int**)(malloc(sizeof(int*)));//memory allocation for double pointer
    for(j=(3*i+1);j<(3*i+4);j++)
    {
    *p = (int*)(malloc(sizeof(int)));//memory allocation for pointer holding integer array
    **p = j;                  
    printf(" %d",**p);//print integers in a row 
    printf("\n");
    p++;
    }
    }
    }

Die Ausgabe des obigen Codes ist:-

1 2 3

4 5 6

7 8 9

Um ein zweidimensionales Array in Bezug auf Zeiger zu verstehen, müssen wir verstehen, wie es im Speicher zugewiesen wird. Es sollte ungefähr so ​​​​aussehen:

                1    2    3
    1000 -->   100  104  108

                4    5    6
    1004 -->   200  204  208

                7    8    9
    1008 -->   300  304  308 

Aus dem Obigen verstehen wir, dass, wenn wir dem Zeiger p, der ein Doppelzeiger ist, Speicher zuordnen, dieser auf ein Array von Ganzzahlen zeigt, also sehen wir in diesem Beispiel, dass 0x1000 der Zeiger p ist.

Dieser Zeiger zeigt auf den ganzzahligen Zeiger *p, der ein Array von ganzen Zahlen ist, wenn Speicher innerhalb der inneren for-Schleife zugewiesen wird, während der ersten Iteration ist der Zeiger 0x100, der auf den ganzzahligen Wert 1 zeigt, wenn wir **p = j zuweisen. In ähnlicher Weise wird es in den nächsten Iterationen in der Schleife auf 2 und 3 zeigen.

Vor der nächsten Iteration der äußeren Schleife wird der Doppelzeiger inkrementiert, innerhalb der nächsten Iteration, wie in diesem Beispiel zu sehen ist, befindet sich der Zeiger jetzt bei 0x1004 und zeigt auf einen ganzzahligen Zeiger, der ein Array von ganzen Zahlen 4,5,6 und ähnlich ist für die nächsten Iterationen in der Schleife.

  • 2d_array ist jedoch kein gültiger Bezeichner!

    – Antti Haapala – Слава Україні

    23. März 2019 um 13:03 Uhr

Benutzer-Avatar
Nander Speerstra

Versuchen Sie den folgenden Code:

 void allocate_mem(int*** arr,int n, int m)
{
  *arr=(int**)malloc(n*sizeof(int*));
  for(int i=0;i<n;i++)
    *(arr+i)=(int*)malloc(m*sizeof(int));
} 

1179650cookie-checkOrdnen Sie Speicher 2d Array in Funktion C zu

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

Privacy policy