将内存分配给包含结构矩阵的结构,结构本身包含整数矩阵
Allocating memory to a struct containing a matrix of struct, itself containing a matrix of integer
所以,我很难理解我应该如何为包含其他结构的结构分配内存。
这是我的两个结构:
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 内的矩阵中的每个约束准备 space ?
我的意思是,我知道约束 ** constraint_matrix 将包含 max_var*max_var 约束,并且在每个约束中,int ** 约束将包含 max_domain * max_domain 诠释。
这是否意味着我必须为 Constraint_mat 准备 max_var * max_var * max_domain * max_domain * sizeof(int) ?
我相信你想写:
Constraint_mat * matrice_contrainte = malloc(1 * sizeof(Constraint_mat);
这只是为堆上 Constraint_mat
类型的一个对象分配足够的内存。
Does that mean that I have to prepare max_var * max_var * max_domain * max_domain * sizeof(int) for Constraint_mat ?
是的,但这不会改变您正在使用的结构的大小。 每个指针都指向内存中的一个区域,在您应用 sizeof() 运算符时未考虑该区域。考虑到您正在使用的第二个结构:
typedef struct{
Constraint ** constraint_matrix;
int max_var;
}Constraint_mat;
需要多少内存?答案是 sizeof(Constraint **) + sizeof(int)
(对于结构中的每个字段)+ 有点随机的数量,取决于其他因素。通常,大多数现代机器上的 sizeof(int) == 4
字节和指针(任何指针,包括指向大量结构、数组等的指针)的大小总是相同的,即对于大多数目的,sizeof(unsigned long) == 4
字节。
通过一些简单的添加,您可以估计您的结构至少 4 + 4 = 8 个字节大小。这个大小总是相对恒定的,永远不会取决于您在实现中使用的 max_var
的值。这意味着,如果您想在矩阵 (matrice_contrainte->constraint_matrix
) 中插入 N * N 个元素,则不必担心 Constraint **
的大小会发生变化。
现在,会发生什么?构建矩阵时,您必须考虑为代表矩阵行的 N 个指针分配内存:
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));
}
从现在开始,我希望步骤变得清晰:
matrice_contrainte->constraint_matrix[i][j]->constraint = (int **) malloc(N * sizeof(int *));
其中 j 从 1 迭代到 N;
matrice_contrainte->constraint_matrix[i][j]->constraint[k] = (int *) malloc(N * sizeof(int));
其中 k 从 1 迭代到 N。
总的来说,您将使用 N^4 内存(这是您所期望的),但您无法使用 sizeof() 运算符来测量它。
确保完成所有必要的 free()
调用。
对于解释过多和英语使用不当,我提前表示歉意。
当您在每个结构中存储一维时,我假设您认为这些是方阵。
我相信你使用指针的指针是为了方便,所以你不需要不连续的内存 space,所以你可以 allocate/deallocate 内存用于一个约束:
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;
}
allocate/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]
都是有效的,当然你需要它们是独立的值。所以每一个pConstraint->constraint[i]
(也就是指向int
的指针)都指定一个地址给nint
留空间。总共是 n * n int
.
我不推荐的第一种方法是为 n int
:
分配空间
for (int i = 0; i < n; i++)
{
pConstraint->constraint[i] = malloc(n * sizeof(int));
}
第二种方法,你只分配一次,然后在分配的大内存中调度c.constraint[i]
s space:
p = malloc(n * n * sizeof(int));
for (int i = 0; i < n; i++)
{
pConstraint->constraint[i] = p + i * n;
}
所以,我很难理解我应该如何为包含其他结构的结构分配内存。
这是我的两个结构:
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 内的矩阵中的每个约束准备 space ? 我的意思是,我知道约束 ** constraint_matrix 将包含 max_var*max_var 约束,并且在每个约束中,int ** 约束将包含 max_domain * max_domain 诠释。 这是否意味着我必须为 Constraint_mat 准备 max_var * max_var * max_domain * max_domain * sizeof(int) ?
我相信你想写:
Constraint_mat * matrice_contrainte = malloc(1 * sizeof(Constraint_mat);
这只是为堆上 Constraint_mat
类型的一个对象分配足够的内存。
Does that mean that I have to prepare max_var * max_var * max_domain * max_domain * sizeof(int) for Constraint_mat ?
是的,但这不会改变您正在使用的结构的大小。 每个指针都指向内存中的一个区域,在您应用 sizeof() 运算符时未考虑该区域。考虑到您正在使用的第二个结构:
typedef struct{
Constraint ** constraint_matrix;
int max_var;
}Constraint_mat;
需要多少内存?答案是 sizeof(Constraint **) + sizeof(int)
(对于结构中的每个字段)+ 有点随机的数量,取决于其他因素。通常,大多数现代机器上的 sizeof(int) == 4
字节和指针(任何指针,包括指向大量结构、数组等的指针)的大小总是相同的,即对于大多数目的,sizeof(unsigned long) == 4
字节。
通过一些简单的添加,您可以估计您的结构至少 4 + 4 = 8 个字节大小。这个大小总是相对恒定的,永远不会取决于您在实现中使用的 max_var
的值。这意味着,如果您想在矩阵 (matrice_contrainte->constraint_matrix
) 中插入 N * N 个元素,则不必担心 Constraint **
的大小会发生变化。
现在,会发生什么?构建矩阵时,您必须考虑为代表矩阵行的 N 个指针分配内存:
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));
}
从现在开始,我希望步骤变得清晰:
matrice_contrainte->constraint_matrix[i][j]->constraint = (int **) malloc(N * sizeof(int *));
其中 j 从 1 迭代到 N;
matrice_contrainte->constraint_matrix[i][j]->constraint[k] = (int *) malloc(N * sizeof(int));
其中 k 从 1 迭代到 N。
总的来说,您将使用 N^4 内存(这是您所期望的),但您无法使用 sizeof() 运算符来测量它。
确保完成所有必要的 free()
调用。
对于解释过多和英语使用不当,我提前表示歉意。
当您在每个结构中存储一维时,我假设您认为这些是方阵。
我相信你使用指针的指针是为了方便,所以你不需要不连续的内存 space,所以你可以 allocate/deallocate 内存用于一个约束:
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;
}
allocate/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]
都是有效的,当然你需要它们是独立的值。所以每一个pConstraint->constraint[i]
(也就是指向int
的指针)都指定一个地址给nint
留空间。总共是 n * n int
.
我不推荐的第一种方法是为 n int
:
for (int i = 0; i < n; i++)
{
pConstraint->constraint[i] = malloc(n * sizeof(int));
}
第二种方法,你只分配一次,然后在分配的大内存中调度c.constraint[i]
s space:
p = malloc(n * n * sizeof(int));
for (int i = 0; i < n; i++)
{
pConstraint->constraint[i] = p + i * n;
}