Ich habe folgenden C
Code:
int *a;
size_t size = 2000*sizeof(int);
a = (int *) malloc(size);
das funktioniert gut. Aber wenn ich folgendes habe:
char **b = malloc(2000*sizeof *b);
wo jedes Element b
eine andere Länge hat.
Wie ist es möglich , das gleiche zu tun b
wie ich für a
; dh der folgende Code würde richtig gelten?
char *c;
size_t size = 2000*sizeof(char *);
c = (char *) malloc(size);
free
für jedemalloc
. Sie müssten diechar*
Variablen durchlaufen , um sie freizugeben, und dann die freigebenchar**
.Die typische Form zum dynamischen Zuweisen eines NxM-Arrays vom Typ T ist
T **a = malloc(sizeof *a * N); if (a) { for (i = 0; i < N; i++) { a[i] = malloc(sizeof *a[i] * M); } }
Wenn jedes Element des Arrays eine andere Länge hat, ersetzen Sie M durch die entsprechende Länge für dieses Element. zum Beispiel
T **a = malloc(sizeof *a * N); if (a) { for (i = 0; i < N; i++) { a[i] = malloc(sizeof *a[i] * length_for_this_element); } }
quelle
free
der zugewiesene Speicher ordnungsgemäß verwendet werden soll?a[i]
, dann kostenlosa
.Die äquivalente Speicherzuordnung für
char a[10][20]
wäre wie folgt.char **a; a=(char **) malloc(10*sizeof(char *)); for(i=0;i<10;i++) a[i]=(char *) malloc(20*sizeof(char));
Ich hoffe das sieht einfach zu verstehen aus.
quelle
Der andere Ansatz wäre, einen zusammenhängenden Speicherblock zuzuweisen, der einen Headerblock für Zeiger auf Zeilen sowie einen Bodyblock zum Speichern tatsächlicher Daten in Zeilen umfasst. Markieren Sie dann einfach den Speicher, indem Sie den Zeigern im Header pro Zeile Adressen des Speichers im Body zuweisen. Es würde wie folgt aussehen:
int** 2dAlloc(int rows, int* columns) { int header = rows * sizeof(int*); int body = 0; for(int i=0; i<rows; body+=columnSizes[i++]) { } body*=sizeof(int); int** rowptr = (int**)malloc(header + body); int* buf = (int*)(rowptr + rows); rowptr[0] = buf; int k; for(k = 1; k < rows; ++k) { rowptr[k] = rowptr[k-1] + columns[k-1]; } return rowptr; } int main() { // specifying column amount on per-row basis int columns[] = {1,2,3}; int rows = sizeof(columns)/sizeof(int); int** matrix = 2dAlloc(rows, &columns); // using allocated array for(int i = 0; i<rows; ++i) { for(int j = 0; j<columns[i]; ++j) { cout<<matrix[i][j]<<", "; } cout<<endl; } // now it is time to get rid of allocated // memory in only one call to "free" free matrix; }
Der Vorteil dieses Ansatzes ist die elegante Speicherfreigabe und die Möglichkeit, mithilfe der Array-ähnlichen Notation auf Elemente des resultierenden 2D-Arrays zuzugreifen.
quelle
double
. Es ist sehr wichtig, dass dies berücksichtigt wird, da dies aufgrund einer falschen Datenausrichtung leicht zu einem Busfehler führen kann. Eine allgemeine Lösung sollte sicherstellen, dass die Datenzeilen an einer 8-Byte-Grenze beginnen, zusätzlichen Zuordnungsraum schaffen und entsprechend angepasst werden, wenn dem primären Zeigersegment Zeilenzeiger zugewiesen werden.columnSizes[]
?Wenn jedes Element in b unterschiedliche Längen hat, müssen Sie Folgendes tun:
int totalLength = 0; for_every_element_in_b { totalLength += length_of_this_b_in_bytes; } return (char **)malloc(totalLength);
quelle
Ich denke, ein 2-Schritt-Ansatz ist am besten, weil c 2-D-Arrays gerecht sind und ein Array von Arrays. Der erste Schritt besteht darin, ein einzelnes Array zuzuweisen und es dann zu durchlaufen, um Arrays für jede Spalte zuzuweisen. Dieser Artikel enthält gute Details.
quelle
Dynamische Speicherzuordnung für 2-D-Arrays
int **a,i; // for any number of rows & columns this will work a = (int **)malloc(rows*sizeof(int *)); for(i=0;i<rows;i++) *(a+i) = (int *)malloc(cols*sizeof(int));
quelle
malloc weist keine bestimmten Grenzen zu, daher muss davon ausgegangen werden, dass es einer Bytegrenze zugeordnet ist.
Der zurückgegebene Zeiger kann dann nicht verwendet werden, wenn er in einen anderen Typ konvertiert wird, da der Zugriff auf diesen Zeiger wahrscheinlich zu einer Verletzung des Speicherzugriffs durch die CPU führt und die Anwendung sofort heruntergefahren wird.
quelle