2016-04-05 4 views
-1

他の構造体を含む構造体にどのようにメモリを割り当てると思いますか?ここ構造体の行列を含む構造体にメモリを割り当て、それ自体が整数の行列を含む

は私の2つの構造体です:

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

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

今、私はこのように始まる、Constraint_matにメモリを割り当てるための関数を作成しよう:

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"); 
} 

私は「どのように理解していませんこれを割り当てると仮定します。 constraint_mat内のマトリックスに入る各制約のためのスペースを用意する必要がありますか? 私は、Constraint ** constraint_matrixにはmax_var * max_var Constraintが含まれ、各Constraintではint ** constraintにmax_domain * max_domain intが含まれることがわかります。 これは、Constraint_matのmax_var * max_var * max_domain * max_domain * sizeof(int)を準備する必要があることを意味しますか?

+0

「何か」とは何ですか? –

+0

これらは「行列」ではなくポインタです。行列は与えられた次元を持つ 'int matrix [5] [6]'のようなものです。 – jdarthenay

+0

@VladfromMoscow mallocの中に?私が知りたいこと。 何かが私の構造の中にあるもののインスタンス化です。 – Traknir

答えて

0

各構造に1つのディメンションを格納するとき、私はそれらが正方行列であるとみなします。

は、私はあなたが便宜上ポインタのポインタを使用すると考えているので、あなたは、この方法は必要ありませ連続したメモリ空間を、あなたは1つの制約のために/割り当て解除メモリを割り当てることができません:

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; 
} 

や機能が割り当てるを/ DEALLOCATE制約行列は次のようになります。

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; 
    } 
} 

編集:allocate_Constraintについての説明()

ですから、制約cを持って、あなたが割り当てたいですそれはallocate_Constraint(&c, n)です。 c.constraint[i]を有効にする必要がありますので、使用することができます。したがって、c.constraintは、n個のポインタをintに格納するのに十分なメモリを必要とします。そのための機能であり:

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

今は有効であるために、すべてのc.constraint[i][j]を必要とし、あなたは彼らが当然の独立した値である必要があります。したがって、それぞれ(intへのポインタ)は、n intのための部屋を持つアドレスを指定します。合計でn * n intです。 、あなたは、一度だけ割り当てる

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

第二の方法、あなたは、大規模な割り当てられたメモリ空間にc.constraint[i]秒を派遣:私はお勧めしません

第一の方法は、n個intのために部屋の割り当てをn個されるだろう:

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

ありがとう、それは動作しますが、実際に私を悩ましていたのは、メモリがここでどのように割り当てられたかです。配列をmallocすると、メモリに一定のサイズが与えられますが、ここでは、 "大行列"に与える各ブロックには、もう一つの "小さな行列"が含まれます。だから、私が "ビッグ・マトリックス"を割り当てるとき、私は小さなマトリス(つまり、私が手動で決めなければならない各小さなマトリックスのサイズ*)を入れるのに十分なサイズを与えなければならないか、それらの数(マトリックスの数*どんなサイズであろうと)。 – Traknir

+0

@ Traknir新しい編集でもっとクリア? – jdarthenay

+0

うん、それは助けてくれてありがとう! – Traknir

0

私はあなたが書きたいと考えている:単純にヒープ上のタイプConstraint_matの一つの目的のために十分なメモリを割り当てるために起こっている

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

これは、Constraint_matのmax_var * max_var * max_domain * max_domain * sizeof(int)を準備する必要があることを意味しますか?

はい、ただし、これで作業している構造のサイズは変わりません。 各ポインタは、sizeof()演算子を適用するときに考慮されないメモリ内のゾーンを指します。それはどのくらいのメモリを必要としない

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

は、私はあなたが作業している第2の構造を考慮し、簡単な方法でそれを説明するつもり?答えはsizeof(Constraint **) + sizeof(int)(構造内のすべてのフィールドについて)+多少ランダムな量で、他の要因に依存します。通常は最新のマシンではsizeof(int) == 4バイト、ポインタ(ANYポインタ、大規模な構造や配列などへのポインタを含む)のサイズは常に同じになります。ほとんどの場合、sizeof(unsigned long) == 4バイトです。

単純に加えて、少なくとも 4 + 4 = 8バイトのサイズになるように構造を見積もることができます。このサイズは常に一定であり、実装で使用しているmax_varの値に決して依存しません。つまり、マトリックスにN * N個の要素(matrice_contrainte->constraint_matrix)を挿入する場合は、Constraint **のサイズが変更される心配はありません。

今、どうなりますか?

:各ポインタのためにあなたがヒープ上に、より多くのメモリを割り当てる必要があり、

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

その後:行列を構築するとき、あなたはあなたの行列の行を表すNポインタにメモリを割り当てることを検討する必要があります

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

以降、この時点から、私は手順を明確にしようとしている願っています:

jは1からNまで反復される
matrice_contrainte->constraint_matrix[i][j]->constraint = (int **) malloc(N * sizeof(int *)); 

matrice_contrainte->constraint_matrix[i][j]->constraint[k] = (int *) malloc(N * sizeof(int)); 
kは合計で1からN.

に反復され、あなたは(あなたが期待したものです)^ 4メモリNを使用しようとしているが、あなたははsizeofを使ってそれを測定することはできません

()演算子。

free()の呼び出しがすべて完了していることを確認してください。

説明の冗長性と英語の使い方が乏しいことをお詫び申し上げます。

+0

その前提は何ですか? 'sizeof(unsigned long)== 4'残念ですが、そうではありません。 https://en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models見ての通り、ダミーのLPP64標準は唯一のものではありません! – jdarthenay

+0

私の答えでは、政治的重心よりも単純さを優先させることが重要だと考えました。 64ビットコンピューティングでの私の経験の欠如についてもお詫び申し上げます。 – Betwixt

+0

簡単にすると間違ったことを言うのは悪いです。 C言語のほとんどの型はプラットフォームに依存するサイズを持つため、 'sizeof'が存在します。 – jdarthenay

関連する問題