因此,我在理解如何将内存分配给包含其他结构的结构时遇到了一些麻烦。
这是我的两个结构:
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 **约束将包含max_domain * max_domain int。 这是否意味着我必须为Constraint_mat准备max_var * max_var * max_domain * max_domain * sizeof(int)?
答案 0 :(得分:0)
我相信你想写:
Constraint_mat * matrice_contrainte = malloc(1 * sizeof(Constraint_mat);
这只是为堆上的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;
需要多少内存?答案是sizeof(Constraint **) + sizeof(int)
(对于结构中的每个字段)+有点随机的数量,可以依赖于其他因素。通常,大多数现代机器上的sizeof(int) == 4
字节和指针的大小(ANY指针,包括指向大型结构,数组等的指针)总是相同的,这在大多数情况下都是{ {1}}字节。
通过一些简单的添加,您可以估计您的结构至少 4 + 4 = 8字节大小。此大小始终相对恒定,并且永远不会取决于您在实现中使用的sizeof(unsigned long) == 4
的值。这意味着,如果您想在矩阵中插入N * N个元素(max_var
),则无需担心matrice_contrainte->constraint_matrix
的大小会发生变化。
现在,会发生什么?构建矩阵时,必须考虑为表示矩阵行的N个指针分配内存:
Constraint **
之后,对于每个指针,您必须在堆上分配更多内存:
matrice_contrainte->constraint_matrix = (Constraint **) malloc(N * sizeof(Constraint *))
从这一点开始,我希望步骤明确:
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 *));
其中k从1迭代到N.
总的来说,您将使用N ^ 4内存(这是您所期望的),但您无法使用sizeof()运算符进行测量。
确保您执行了所有必要的matrice_contrainte->constraint_matrix[i][j]->constraint[k] = (int *) malloc(N * sizeof(int));
来电。
我提前道歉,因为解释冗余和英语使用不当。
答案 1 :(得分:0)
当您在每个结构中存储一个维度时,我假设您认为这些是方形矩阵。
我相信您使用指针指针是为了方便,因此您不需要连续的内存空间,因此您可以通过这种方式为一个约束分配/释放内存:
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;
}
分配/解除分配约束矩阵的函数可以是:
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
需要足够的内存来存储指向int
的n个指针。因此在函数中有:
pConstraint->constraint = malloc(n * sizeof(int *));
现在您需要所有c.constraint[i][j]
有效,并且您当然需要它们是独立的值。因此,每个pConstraint->constraint[i]
(指向int
的指针)指定一个具有n int
空间的地址。总数为n * n int
。
我不建议使用第一种方法,即为int
分配空间:
for (int i = 0; i < n; i++)
{
pConstraint->constraint[i] = malloc(n * sizeof(int));
}
第二种方法,只分配一次,然后在大的已分配内存空间中调度c.constraint[i]
:
p = malloc(n * n * sizeof(int));
for (int i = 0; i < n; i++)
{
pConstraint->constraint[i] = p + i * n;
}