2016-04-05 10 views
-1

enthält. Also habe ich Probleme damit zu verstehen, wie ich Speicher einer Struktur zuweisen soll, die andere Struktur enthält.Zuordnen von Speicher zu einer Struktur, die eine Matrix von struct enthält, die selbst eine Matrix von Integer

hier sind meine zwei struct:

typedef struct{ 
    int ** constraint; 
    int max_domain; 
}Constraint; 

typedef struct{ 
    Constraint ** constraint_matrix; 
    int max_var; 
}Constraint_mat; 

Nun ich versuche, eine Funktion zu erstellen Speicher zu einem Constraint_mat zuzuweisen, wie dies Start:

Constraint_mat * allocationConstraintMatrix(int max_var){ 
    printf("Initialisation Matrice de Contrainte : allocation mémoire\n"); 
    Constraint_mat * matrice_contrainte = malloc(max_var*(max_var-1)*(sizeof *matrice_contrainte)) 
    matrice_contrainte->max_var = max_var; 
    matrice_contrainte->constraint_matrix = malloc(max_var*sizeof(matrice_contrainte->constraint_matrix)); 
    if(matrice_contrainte->constraint_matrix == NULL){ 
     printf("Erreur allocation memoire matrice de contrainte\n"); 
     exit(-1); 
    } 
    for(int i = 0; i < max_var; i++){ 
     matrice_contrainte->constraint_matrix[i] = malloc(max_var*sizeof(matrice_contrainte->constraint_matrix[i])); 
     if(matrice_contrainte->constraint_matrix[i] == NULL){ 
      printf("erreur allocation memoire matrice de domaine\n"); 
      exit(-1); 
     } 
    } 
    printf("Succes\n"); 
} 

Ich verstehe nicht, wie ich Ich nehme an, dies zuzuteilen. Muss ich Platz für jede Einschränkung vorbereiten, die in der constraint_mat-Matrix enthalten ist? Ich meine, ich weiß, dass Constraint ** constraint_matrix max_var * max_var Constraint enthalten wird, und dass in jeder Constraint int ** Constraint max_domain * max_domain int enthalten wird. Bedeutet das, dass ich max_var * max_var * max_domain * max_domain * sizeof (int) für Constraint_mat vorbereiten muss?

+0

Was ist "etwas"? –

+0

Das sind keine "Matrizen", sondern Zeiger. Eine Matrix wäre etwas wie "int Matrix [5] [6]" mit gegebenen Dimensionen. – jdarthenay

+0

@VladfromMoscow Im malloc? Was ich wissen will. Und das etwas andere ist die Instanziierung dessen, was in meiner Struktur ist – Traknir

Antwort

0

Da Sie eine Dimension in jeder Struktur speichern, gehe ich davon aus, dass dies quadratische Matrizen sind.

Ich glaube, Sie Zeiger von Zeigern für Bequemlichkeit verwenden, so dass Sie nicht brauchen, nicht zusammenhängenden Speicherplatz, so könnten Sie/Freisetzen für eine Einschränkung auf diese Weise Speicher reservieren:

int allocate_Constraint(Constraint *pConstraint, int n) 
{ 
    // You need room for n * n integers, right ? 
    int *p = malloc(n * n * sizeof(int)); 
    if (p == NULL) 
    { 
     return 0; // memory insufficient => return false 
    } 

    // You need room for n pointers to integer 
    pConstraint->constraint = malloc(n * sizeof(int *)); 
    if (pConstraint->constraint == NULL) 
    { 
     free(p); 
     return 0; // memory insufficient => return false 
    } 

    for (int i = 0; i < n; i++) 
    { 
     // Each line starts n integers farther than the previous one 
     pConstraint->constraint[i] = p + n * i; 
    } 

    // Now it's good, your matrix is usable. 
    pConstraint->max_domain = n; 
    return 1; 
} 

void deallocate_Constraint(Constraint *pConstraint) 
{ 
    if (pConstraint->max_domain > 0) 
    { 
     free(pConstraint->constraint[0]); 
     free(pConstraint->constraint); 
     pConstraint->constraint = NULL; 
     pConstraint->max_domain = 0; 
    } 
} 

int main() 
{ 
    Constraint c = {constraint: NULL, max_domain:0}; 
    if (allocate_Constraint(&c, 10)) 
    { 
     // do stuff with c 
     deallocate_Constraint(&c); 
    } 
    return 0; 
} 

und Funktionen zuweisen/ausplanen Constraint-Matrizen könnten sein:

int allocate_Constraint_mat(Constraint_mat *pConstraint_mat, int n) 
{ 
    // You need room for n * n Constraint(s), right ? 
    Constraint *p = malloc(n * n * sizeof(Constraint)); 
    if (p == NULL) 
    { 
     return 0; // memory insufficient => return false 
    } 

    // You need room for n pointers to Constraint 
    pConstraint_mat->constraint_matrix = malloc(n * sizeof(Constraint *)); 
    if (pConstraint_mat->constraint_matrix == NULL) 
    { 
     free(p); 
     return 0; // memory insufficient => return false 
    } 

    for (int i = 0; i < n; i++) 
    { 
     // Each line starts n Constraint(s) farther than the previous one 
     pConstraint_mat->constraint_matrix[i] = p + n * i; 
    } 

    // Initializing to empty matrices 
    for (int i = 0; i < n; i++) 
    { 
     for (int j = 0; j < n; j++) 
     { 
      pConstraint_mat->constraint_matrix[i][j].constraint = NULL; 
      pConstraint_mat->constraint_matrix[i][j].max_domain = 0; 
     } 
    } 

    // Now it's good, your matrix is usable. 
    pConstraint_mat->max_var = n; 
    return 1; 
} 

void deallocate_Constraint_mat(Constraint_mat *pConstraint_mat) 
{ 
    if (pConstraint_mat->max_var > 0) 
    { 
     free(pConstraint_mat->constraint_matrix[0]); 
     free(pConstraint_mat->constraint_matrix); 
     pConstraint_mat->constraint_matrix = NULL; 
     pConstraint_mat->max_var = 0; 
    } 
} 

Edit: Erläuterungen zu allocate_Constraint()

So haben Sie eine Constraint c, möchten Sie zuzuteilen es mit allocate_Constraint(&c, n). Sie müssen jeweils c.constraint[i] gültig sein, damit Sie es verwenden können. So brauchen c.constraint genug Speicher, um n Zeiger auf int zu speichern. Daher wird in der Funktion gibt es:

pConstraint->constraint = malloc(n * sizeof(int *)); 

Jetzt müssen Sie alle c.constraint[i][j] gültig sein, und Sie müssen sie unabhängige Werte natürlich sein. Also jedes pConstraint->constraint[i] (das ist ein Zeiger auf int), um eine Adresse mit Platz für n int zu bezeichnen. Insgesamt sind das n * n int.

erste Methode, die ich nicht empfehlen würde Zuteilung von Raum für n werden n int:

for (int i = 0; i < n; i++) 
{ 
    pConstraint->constraint[i] = malloc(n * sizeof(int)); 
} 

Zweite Methode ordnen Sie nur einmal, und Sie schicken die c.constraint[i] s im großen Speicherplatz zugewiesen :

p = malloc(n * n * sizeof(int)); 
for (int i = 0; i < n; i++) 
{ 
    pConstraint->constraint[i] = p + i * n; 
} 
+0

Danke, es funktioniert, aber eigentlich, was mich gestört hat, war mehr, wie der Speicher hier zugeordnet ist. Wenn Sie ein Array mallokieren, geben Sie ihm eine bestimmte Größe im Speicher, aber hier enthält jeder Block, den Sie der "großen Matrix" geben, eine andere "kleine Matrix" darin. Also wenn ich die "große Matrix" zuteile, wollte ich wissen, ob ich ihm genügend Größe geben muss, um auch jede kleine Matrize (dh die Größe jeder kleinen Matrix (die ich manuell bestimmen muss) * ihre Nummer) oder einfach zu enthalten ihre Nummer (Nummer der Matrix * wie groß sie auch ist). – Traknir

+0

@Traknir klarer mit neuer Bearbeitung? – jdarthenay

+0

yep danke es hilft! – Traknir

0

Ich glaube, Sie schreiben wollen:

Constraint_mat * matrice_contrainte = malloc(1 * sizeof(Constraint_mat); 

die einfach wird genug Speicher für ein Objekt vom Typ Constraint_mat auf dem Heap reservieren.

Bedeutet das, dass ich max_var * max_var * max_domain * max_domain * sizeof (int) für Constraint_mat vorbereiten muss?

Ja, aber das ändert nicht die Größe der Strukturen, mit denen Sie arbeiten. Jeder der Zeiger zeigt auf eine Zone im Speicher, die beim Anwenden des Operators sizeof() nicht berücksichtigt wird. Ich werde es auf einfachere Art und Weise zu erklären, die zweite Struktur unter Berücksichtigung mit dem Sie arbeiten:

typedef struct{ 
    Constraint ** constraint_matrix; 
    int max_var; 
}Constraint_mat; 

Wie viel Speicher braucht es? Die Antwort ist sizeof(Constraint **) + sizeof(int) (für jedes Feld in Ihrer Struktur) + eine etwas zufällige Menge, die von anderen Faktoren abhängig ist. Normalerweise sizeof(int) == 4 Bytes auf den meisten modernen Maschinen, und die Größe eines Zeigers (beliebiger Zeiger, einschließlich Zeiger auf massive Strukturen, Arrays und so weiter) wird immer der gleiche sein, der für die meisten Zwecke sizeof(unsigned long) == 4 Bytes ist.

Mit einigen einfachen zusätzlichen, können Sie Ihre Struktur zu mindestens 4 + 4 = 8 Bytes Größe schätzen. Diese Größe wird immer relativ konstant sein und wird niemals von dem Wert max_var abhängen, den Sie in Ihrer Implementierung verwenden. Das heißt, wenn Sie N * N Elemente in Ihre Matrix einfügen möchten (matrice_contrainte->constraint_matrix), müssen Sie sich keine Gedanken über die Größe von Constraint ** machen, um sich jemals zu ändern.

Nun, was wird passieren?Wenn die Matrix bauen, müssen Sie überlegen, Speicher für die N-Pointer Zuweisung, die die Zeilen Ihrer Matrix darstellen:

matrice_contrainte->constraint_matrix = (Constraint **) malloc(N * sizeof(Constraint *))

Danach für jeden Zeiger müssen Sie mehr Speicher auf dem Heap reservieren:

int i = 0; 
for(i = 0; i < N; i++) { 
    matrice_contrainte->constraint_matrix[i] = (Constraint *) malloc(N * sizeof(Constraint)); 
} 

von diesem Punkt an, ich hoffe, dass die Schritte klar sein werden:

matrice_contrainte->constraint_matrix[i][j]->constraint = (int **) malloc(N * sizeof(int *)); 

wobei j von 1 bis N iteriert;

matrice_contrainte->constraint_matrix[i][j]->constraint[k] = (int *) malloc(N * sizeof(int)); 

wobei k von 1 bis N Iterieren

Insgesamt werden Sie N^4-Speicher zu verwenden (das ist, was Sie erwartet), aber man kann es nicht messen die sizeof mit() Operator.

Stellen Sie sicher, dass Sie alle notwendigen free() Anrufe tätigen.

Ich entschuldige mich im Voraus für Redundanz in der Erklärung und schlechte Verwendung von Englisch.

+0

Was ist diese Annahme? 'sizeof (unsigned long) == 4' Es tut mir leid, aber nein, das stimmt nicht. https://en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models Wie Sie sehen können, ist der Dummy-LPP64-Standard nicht der einzige! – jdarthenay

+0

In meiner Antwort hielt ich es für wichtiger, Einfachheit gegenüber politischer Korrektheit zu priorisieren. Ich entschuldige mich auch für meinen Mangel an Erfahrung im 64-Bit-Computing. – Betwixt

+0

Es ist schlecht, der Einfachheit halber etwas falsches zu sagen. 'sizeof' existiert, weil die meisten Typen in C plattformabhängige Größen haben. – jdarthenay

Verwandte Themen