将内存分配给包含结构矩阵的结构,结构本身包含整数矩阵

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