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

时间:2016-04-05 17:37:10

标签: c struct allocation

因此,我在理解如何将内存分配给包含其他结构的结构时遇到了一些麻烦。

这是我的两个结构:

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)?

2 个答案:

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