尝试在 C 中动态分配并设置为 0 矩阵,但我无法将设置为 0 的部分工作

Trying to allocate and set to 0 a matrix dynamically in C, but I can't get the set to 0 part to work

提问人:Gianni Trattore 提问时间:8/31/2022 最后编辑:Steve FriedlGianni Trattore 更新时间:9/1/2022 访问量:68

问:

我有我需要的这个矩阵初始化函数:我可以毫无问题地生成它,但不能将其所有值初始化为 0,无论是使用还是通过矩阵元素上的循环。calloc

功能如下:

int initMTX(int r, int c, int ***MTX) {
  int **locMTX = malloc(r * sizeof(int *)), i, j;
  for (i = 0; i < r; i++) {
    locMTX[i] = (int *)malloc(c * sizeof(int));
  }
  for (i = 0; i < r; i++)
    for (j = 0; j < c; j++)
      locMTX[i][j] = 0;
  *MTX = locMTX;

  return 1;
}

如果需要上下文,整个代码如下:

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

int initMTX(int r, int c, int ***MTX);
void printMTX(int r, int c, int **MTX);
void freeMTX(int r, int **MTX);

int main(void) {
  int NBits = 4, NNumbers = 2 ^ NBits, **MTXResults;
  initMTX(NNumbers, NBits, &MTXResults);
  // code
  printMTX(NNumbers, NBits, MTXResults);
  freeMTX(NNumbers, MTXResults);
}

int initMTX(int r, int c, int ***MTX) {
  int **locMTX = malloc(r * sizeof(int *)), i, j;
  for (i = 0; i < r; i++) {
    locMTX[i] = (int *)malloc(c * sizeof(int));
  }
  for (i = 0; i < r; i++)
    for (j = 0; j < c; j++)
      locMTX[i][j] = 0;
  *MTX = locMTX;
  return 1;
}

void printMTX(int r, int c, int **MTX) {
  int i, j;
  for (i = 0; i < r; i++) {
    for (j = 0; j < c; j++)
      printf("%d ", MTX[i][r]);
    printf("\n");
  }
}

void freeMTX(int r, int **MTX) {
  for (int i = 0; i < r; i++)
    free(MTX[i]);
  free(MTX);
}

我以为我现在已经很好地掌握了这样的事情,但事实证明并非如此,所以我被困了一段时间。 如果可能的话,我也希望在使用时知道问题出在哪里。calloc

C 卡洛克

评论

2赞 n. m. could be an AI 8/31/2022
printf("%d ", MTX[i][r]);<-- 这里
4赞 Some programmer dude 8/31/2022
2 ^ NBits可能不是你想要的。 是按位异或。请改用 shift。^
5赞 Weather Vane 8/31/2022
该函数始终返回 .与其纠结于三星指针参数,不如返回一个两星指针1
2赞 Barmar 8/31/2022
MTX[i][r]应该是MTX[i][j]
2赞 n. m. could be an AI 8/31/2022
@Barmar 第一手经验比二手经验更有价值。我发现错别字很好,OP找到错别字更好。OP 在没有我指向行的情况下找到错别字是最好的,但这意味着告诉他们“使用你有福的调试器”,我厌倦了这句话。

答:

0赞 Jonathan Leffler 9/1/2022 #1

此代码修复了问题中代码中的错误(最明显的是拼写错误变为 ),并实现了 .它还包括用于在创建矩阵时从内存分配失败中恢复的代码。MTX[i][r]MTX[i][j]freeMTX()

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

int initMTX(int r, int c, int ***MTX);
void printMTX(int r, int c, int **MTX);
void freeMTX(int r, int **MTX);

int main(void)
{
    int NBits = 4;
    int NNumbers = 16;
    int **MTXResults;

    if (initMTX(NNumbers, NBits, &MTXResults))
    {
        printMTX(NNumbers, NBits, MTXResults);
        freeMTX(NNumbers, MTXResults);
    }
    else
        fprintf(stderr, "failed to allocate %dx%d matrix\n", NBits, NNumbers);
}

int initMTX(int r, int c, int ***MTX)
{
    int **locMTX = malloc(r * sizeof(int *));
    if (locMTX == 0)
        return 0;
    for (int i = 0; i < r; i++)
    {
        locMTX[i] = (int *)malloc(c * sizeof(int));
        if (locMTX[i] == 0)
        {
            for (int j = 0; j < i; j++)
                free(locMTX[j]);
            free(locMTX);
            return 0;
        }
    }
    for (int i = 0; i < r; i++)
    {
        for (int j = 0; j < c; j++)
            locMTX[i][j] = 0;
    }

    *MTX = locMTX;
    return 1;
}

void printMTX(int r, int c, int **MTX)
{
    for (int i = 0; i < r; i++)
    {
        for (int j = 0; j < c; j++)
            printf("%d ", MTX[i][j]);
        printf("\n");
    }
}

void freeMTX(int r, int **MTX)
{
    for (int i = 0; i < r; i++)
        free(MTX[i]);
    free(MTX);
}

此代码使用更简单的两个分配方案,在两个注释中概述:

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

int initMTX(int r, int c, int ***MTX);
void printMTX(int r, int c, int **MTX);
void freeMTX(int **MTX);

int main(void)
{
    int NBits = 4;
    int NNumbers = 16;
    int **MTXResults;

    if (initMTX(NNumbers, NBits, &MTXResults))
    {
        printMTX(NNumbers, NBits, MTXResults);
        freeMTX(MTXResults);
    }
    else
        fprintf(stderr, "failed to allocate %dx%d matrix\n", NBits, NNumbers);
}

int initMTX(int r, int c, int ***MTX)
{
    int **locMTX = malloc(r * sizeof(locMTX[0]));
    if (locMTX == 0)
        return 0;
    int *data = malloc(r * c * sizeof(locMTX[0][0]));
    if (data == 0)
    {
        free(locMTX);
        return 0;
    }
    for (int i = 0; i < r; i++)
    {
        locMTX[i] = data + i * c;
        for (int j = 0; j < c; j++)
            locMTX[i][j] = 0;
    }

    *MTX = locMTX;
    return 1;
}

void printMTX(int r, int c, int **MTX)
{
    for (int i = 0; i < r; i++)
    {
        for (int j = 0; j < c; j++)
            printf("%d ", MTX[i][j]);
        printf("\n");
    }
}

void freeMTX(int **MTX)
{
    free(MTX[0]);
    free(MTX);
}

释放代码要简单得多,创建矩阵时的错误恢复也要简单得多——主要是因为只有两个分配可能会失败。