【问题标题】:Tried to do 3 dimensional matrix using malloc尝试使用 malloc 做 3 维矩阵
【发布时间】:2021-11-05 06:31:35
【问题描述】:

我想使用malloc 收集一个 3 维矩阵。还有矩阵打印部分,但我没有包括。

#include <stdio.h>
#include <stdlib.h>
int main()
{
   int i,j,k,m,n,o;
   float ***A;
   printf("Input dimension for matrix(m,n,o)\n");
   printf("Enter m : ");
   scanf("%d",&m);
   printf("Enter n : ");
   scanf("%d",&n);
   printf("Enter o : ");
   scanf("%d",&o);
   A = (float***)malloc(o*sizeof(float**));
   for(i=0;i<o;i++){
           A[i] = (float**)malloc(m*sizeof(float*));
           for(j=0;j<m;j++){
               A[i][j] = (float*)malloc(n*sizeof(float));
           }
   }
   for(i=0;i<o;i++){
       for(j=0;j<m;j++){
           for(k<0;k<n;k++){
               printf("Input number for (%d,%d,%d) : ",j+1,k+1,i+1);
               scanf("%f",&A[i][j][k]);
           }
       }
   }
   return 0;
}

在我完成输入 m,n,o 后程序似乎跳到最后,所以我无法输入任何矩阵值。我必须使用malloc,因为它是任务所必需的。

编辑:一切都是错误的。 m代表行,n代表列,o代表mXn矩阵的个数。

【问题讨论】:

  • 第一个循环for(i=0;i&lt;n;i++)不应该是for(i=0;i&lt;o;i++),因为你分配了o数组元素吗?以下也是。
  • 您似乎对 malloc 和 for 循环使用了不同的数字。例如。如果维度为 111,222,333,则分配 111 个 float**s,然后将 222 个指针放入该空间。
  • 请不要让代码成为“移动目标”!
  • 注意编译器警告。 scanf("%f",A[i][j][k])错了,应该是&amp;A[i][j][k]
  • 下一个编译器警告是for(k&lt;0;k&lt;m;k++) 启用所有警告

标签: c matrix malloc


【解决方案1】:

使用动态可变长度数组:

float (*A)[n][m] = calloc(o, sizeof *A);

并在最后释放它

free(A);

更多的人必须传递scanf-ed对象的地址,而不是它的值。应该是:

scanf("%f", &A[i][j][k])

【讨论】:

  • 对不起。但是 float A*** 不能从代码中删除。所以我不能使用动态 VLA。
  • @SecretNumber 这是为 3D 数组分配的。 float A*** 方法不是 3D 数组,而是指向float 数组的指针数组的指针数组。
  • @chux-ReinstateMonica 我的家庭作业任务固定为float A***。所以我不得不改用那个方法。
  • @SecretNumber 好的,所以你不想要一个真正的 3D 数组,而是一个 jagged array。抱歉,如果您的课程没有使用清晰的术语。
【解决方案2】:

这应该可行:

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    float ***A;

    // n1, n2 and n3 will contain the three dimensions (i.e.: A[n1][n2][n3])
    size_t n1, n2, n3;

    printf("Insert first dimension: ");
    if (scanf("%zu", &n1) != 1) {
        printf("ERROR: cannot read number\n");
        return 1;
    }

    printf("Insert second dimension: ");
    if (scanf("%zu", &n2) != 1) {
        printf("ERROR: cannot read number\n");
        return 1;
    }

    printf("Insert third dimension: ");
    if (scanf("%zu", &n3) != 1) {
        printf("ERROR: cannot read number\n");
        return 1;
    }

    // firstly, here we alloc space for first dimension
    A = malloc(n1 * sizeof(float**));

    for (size_t i = 0; i < n1; i += 1) {
        // now we alloc space for second dimension
        A[i] = malloc(n2 * sizeof(float*));
        for (size_t j = 0; j < n2; j += 1) {
            // here we alloc space for third dimension
            A[i][j] = malloc(n3 * sizeof(float));
        }
    }

    // let's ask the user to input all elements into the array
    for (size_t i = 0; i < n1; i += 1) {
        for (size_t j = 0; j < n2; j += 1) {
            for (size_t k = 0; k < n3; k += 1) {
                printf("Insert value for A[%zu][%zu][%zu]: ", i, j, k);
                if (scanf("%f", &(A[i][j][k])) != 1) {
                    printf("ERROR: cannot read number\n");
                    return 1;
                }
            }
        }
    }

    // now let's print all the numbers that the user has input previously
    for (size_t i = 0; i < n1; i += 1) {
        for (size_t j = 0; j < n2; j += 1) {
            for (size_t k = 0; k < n3; k += 1) {
                printf("A[%zu][%zu][%zu] = %f\n", i, j, k, A[i][j][k]);
            }
        }
    }

    return 0;
}

我没有编译它,但它应该是正确的。仔细看看是如何分配的。

注意:当然,完全正确(例如:使用 free() 和避免使用 scanf())是故意避免的。

P.S.:正如其他用户已经提到的,请注意为您的编译器启用警告(例如:GCC 上的 -Wall -Wextra),因为它会为您简化调试。

【讨论】:

  • 分配给被引用对象的大小而不是分配给类型的大小,更不容易出错并且更容易维护。 arr = malloc(n1 * sizeof *arr);
  • @chux-ReinstateMonica 是的,你的方法是一种不错的替代方法。
  • @LucaPolito 对不起。但正如我上面所说。我无法将float A*** 更改为其他任何内容。
  • @SecretNumber 此答案使用float***。这怎么不能实现你的目标?
  • @SecretNumber 看起来更好。我没有更改您的float ***A,只是将其重命名为arr。您可以根据需要将arr 替换为A
【解决方案3】:

我认为你所做的只是在获取输入时在 for 循环中搞砸了。根据上下文,3D 矩阵,我调试了代码并提出了一个有意义的版本。

我会继续指出你犯的错误。

首先,scanf 获取变量的内存地址,而不是它的取消引用版本。

因此,将其从 scanf("%f",A[i][j][k]); 更改为 scanf("%f",&amp;(A[i][j][k]));。这个也可以scanf("%f",A[i][j] + k);

在这一行中,for(k&lt;0;k&lt;n;k++)k 甚至没有被初始化。因此,您实际上是在对垃圾值进行操作。由于我已经对破译c pointer hell 感到困惑,我什至无法处理最终结果。更有意义的代码是 for(k=0;k&lt;n;k++)

之后,你切换了嵌套for循环的控制逻辑。

将此代码for(j=0;j&lt;m;j++) 中的变量m 替换为nfor(j=0;j&lt;n;j++)

在下一个循环中反之亦然。将此for(k=0;k&lt;n;k++)修改为for(k=0;k&lt;m;k++)

最终的代码如下所示,

#include <stdio.h>
#include <stdlib.h>
int main()
{
   int i,j,k,m,n,o;
   float ***A;
   printf("Input dimension for matrix(m,n,o)\n");
   printf("Enter m : ");
   scanf("%d",&m);
   printf("Enter n : ");
   scanf("%d",&n);
   printf("Enter o : ");
   scanf("%d",&o);
   A = (float***)malloc(o*sizeof(float**));
   for(i=0;i<o;i++){
           A[i] = (float**)malloc(n*sizeof(float*));
           for(j=0;j<n;j++){
               A[i][j] = (float*)malloc(m*sizeof(float));
           }
   }
   for(i=0;i<o;i++){
       for(j=0;j<n;j++){
           for(k=0;k<m;k++){
               printf("Input number for (%d,%d,%d) : ", i + 1, j + 1, k + 1);
               scanf("%f",&(A[i][j][k]));
           }
       }
   }
   
   
   return 0;
}

它现在可以用作 3D 矩阵。

为了理解代码,我不得不画一个凌乱的图表。我附上那个。它可能会有所帮助。

由于您已经省略了一些代码,我希望您没有忘记使用free 来防止内存泄漏。

【讨论】:

  • 哦,是的。我没有看到 k
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多