【问题标题】:Can't allocate memory for triple pointer无法为三重指针分配内存
【发布时间】:2020-09-22 03:38:22
【问题描述】:

我正在为学校做一个项目,但我遇到了一个问题,我不知道如何解决它。我正在尝试为函数中的三重指针分配内存,我将能够将其用作二维数组,保存数据然后在不同的函数中使用它。但是由于某种原因,一旦我退出该功能,我就无法使用这些数据。

顺便说一句,我必须使用函数中写入的变量 (float m1[ROWS][COLS], float m2[ROWS][COLS], float ***C).

int mat_mul(float m1[ROWS][COLS], float m2[ROWS][COLS], float ***C)
{
    int i, j, k;

    C = (float ***)malloc(sizeof(float*) * 3);
    for (i = 0; i < 3; i++) {
        C[i] = (float **)malloc(sizeof(float*) * 3); 
    for (j = 0; j < 3; j++) {
            C[i][j] = (float *)malloc(sizeof(float) *3);
        }
    }


        for (i = 0; i < ROWS; i++) {
            for (j = 0; j < COLS; j++) {
                (*C)[i][j] = 0;
                for (k = 0; k < ROWS; k++) {
                    (*C)[i][j] += m1[i][k] * m2[k][j];
                }
            }
        }

        printf_s("%.1f\n", (*C)[0][0]);
}
    int i,j;
    float Results[ROWS][COLS];
    float Angle1[6], Angle2[6];
    Angle_Reader("data_q.csv", &Angle1, &Angle2);
    Angle_Converter(&Angle1, &Angle2);


    for (i = 0; i < 1; i++) {
        float Matrix1[ROWS][COLS] = { {cos(Angle1[i]),-sin(Angle1[i]),L1*cos(Angle1[i])},{sin(Angle1[i]),cos(Angle1[i]),L1*sin(Angle1[i])},{0,0,1} };
        float Matrix2[ROWS][COLS] = { {cos(Angle2[i]),-sin(Angle2[i]),L2*cos(Angle2[i])},{sin(Angle2[i]),cos(Angle2[i]),L2*sin(Angle2[i])},{0,0,1} };
        mat_mul(&Matrix1, &Matrix2, &Results);
    }



    printf_s("\n");

    printf_s("%.1f\n", Results[0][0]);

【问题讨论】:

  • 欢迎来到 SO。你为什么想做这个?如果你的参数列表中有一个三重指针,它可能是一个输出参数,你可以在其中放置一个双指针。在函数中分配三重指针没有意义。它在该函数之外是不可见的。
  • 当您调用mat_mul 时,您不需要使用数组的地址。仅名称就已经衰减为指针。无论如何,第三个参数都会被忽略,因为您会立即丢弃 C 并替换为新分配的地址。
  • 我同意现有的 cmets,显示的代码中没有任何内容需要为 3D 矩阵 创建空间。对此的建议,以及下面回答中提供的其他问题。
  • 不要强制转换 malloc 返回的值。

标签: arrays c pointers malloc heap-memory


【解决方案1】:

这个:

for (i = 0; i < 1; i++) {
    float Matrix1[ROWS][COLS] = { {cos(Angle1[i]),-sin(Angle1[i]),L1*cos(Angle1[i])},{sin(Angle1[i]),cos(Angle1[i]),L1*sin(Angle1[i])},{0,0,1} };
    float Matrix2[ROWS][COLS] = { {cos(Angle2[i]),-sin(Angle2[i]),L2*cos(Angle2[i])},{sin(Angle2[i]),cos(Angle2[i]),L2*sin(Angle2[i])},{0,0,1} };
    mat_mul(&Matrix1, &Matrix2, &Results);
}

不应按原样处于循环中。

要么将声明移到循环上方,然后在循环中,使用索引值(即Matrix2[i][j])而不是ROWS, COLS

float Matrix1[ROWS][COLS] = {0};
float Matrix2[ROWS][COLS] = {0};

//Note: these initializers work only for 3x3 array
//Forcing ROWS == 3 and COLS == 3
float data1[ROWS][COLS] = { {cos(Angle1[0]),-sin(Angle1[1]),L1*cos(Angle1[2])},{sin(Angle1[0]),cos(Angle1[1]),L1*sin(Angle1[2])},{0,0,1} };
float data2[ROWS][COLS] = { {cos(Angle2[0]),-sin(Angle2[1]),L2*cos(Angle2[2])},{sin(Angle2[0]),cos(Angle2[1]),L2*sin(Angle2[2])},{0,0,1} };
 ...
 if(Results)
 {
     for (i = 0; i < 1; i++) 
     {
        Matrix1[i][j] = data1[i][j];
        Matrix2[i][j] = data2[i][j];
        ...
        mat_mul(&Matrix1, &Matrix2, &Results);
     }

...或 完全删除 for 循环并将 ij 索引从 Angle1[i] 修改为硬编码值,例如:@987654328 @ 以便初始化器填充二维数组。

float Matrix1[ROWS][COLS] = { {cos(Angle1[0]),-sin(Angle1[1]),L1*cos(Angle1[2])},{sin(Angle1[0]),cos(Angle1[1]),L1*sin(Angle1[2])},{0,0,1} };
float Matrix2[ROWS][COLS] = { {cos(Angle2[0]),-sin(Angle2[1]),L2*cos(Angle2[2])},{sin(Angle2[0]),cos(Angle2[1]),L2*sin(Angle2[2])},{0,0,1} };
mat_mul(&Matrix1, &Matrix2, &Results);

关于创建内存,您的代码中没有任何内容表明需要 3D 数组。如 cmets 所述,float ***Cmat_mul(., ., float ***C) 函数原型中的原因是为了在调用函数时适应 传递 2D 矩阵的地址(例如 &amp;Results ),以便它可以被修改。即使这样,将创建该变量的内存所需的逻辑移动到它自己的函数中,并在它作为变量传递之前分配内存,这将是一种改进:

 float **Results = Create2D(COLS, ROWS);
 if(Results)
 {
     for (i = 0; i < 1; i++) 
     {
        ...
        ...
        mat_mul(&Matrix1, &Matrix2, &Results);
     }
     //When finished using, free Results
     free2D(Results, COLS)

函数Create2D() 及其伴侣可以实现为:

float ** Create2D(int c, int r)
{   
    float **arr;
    int    y;

    arr   = calloc(c, sizeof(float *));
    for(y=0;y<c;y++)
    {
        arr[y] = calloc(r, sizeof(float));    
    }
    return arr;
}

void free2D(float **arr, int c)
{
    int i;
    for(i=0;i<c;i++)
    {
        free(arr[i]);
    }
    free(arr);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-14
    • 1970-01-01
    • 2013-01-07
    • 2012-06-02
    • 1970-01-01
    • 2013-01-29
    • 2021-06-22
    相关资源
    最近更新 更多