【问题标题】:Cannot print out the values of a dynamic 2D array of structs无法打印出动态二维结构数组的值
【发布时间】:2020-06-25 15:38:53
【问题描述】:

这个程序应该向用户询问两个值,然后使用这两个值分别作为行数和列数生成并打印一个表格。表格的每个单元格都有两个值,分别表示为 cellX 和 cellY。表格中每个单元格的 x 值和 y 值分别为 1 和 2。

简而言之,它是一个动态的二维结构数组。问题是,程序似乎跳过了最后一个 for 循环,所以它没有打印结构数组的内容。没有产生错误。

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

typedef struct          // one cell of a table holding two int values
{
    int *cellX;
    int *cellY;
} Table;

int main()
{
    char dump;
    int row, col, y, x;

    printf("Enter number of rows and columns (r,c): ");
    scanf("%d%c%d", &row, &dump, &col);

    Table **grid;
    grid = (Table **)malloc(row * col * sizeof(Table));

    for (y = 0; y < row; y++)           // assigns values to the table
    {
        for (x = 0; x < col; x++)
        {
            *grid[x][y].cellX = 1;      // all x-values will be 1
            *grid[x][y].cellY = 2;      // all y-values will be 2
        }
    }

    for (y = 0; y < row; y++)           // displays the table
    {
        for (x = 0; x < col; x++)
        {
            printf("%d, %d\t", *grid[x][y].cellX, *grid[x][y].cellY);
        }
    }

    free(grid);

    return 0;
}

【问题讨论】:

  • 您将cellXcellY 声明为int *,但您没有分配任何内存供这些指针指向。你认为*grid[x][y].cellX 在第一个双循环中指向哪里?

标签: c arrays struct printf malloc


【解决方案1】:
grid = (Table **)malloc(row * col * sizeof(Table));

这不是你分配二维数组的方式,Table** 是指向Table 数组的指针数组 (Table*),因此你必须分配所有这些单独的子数组。

Table **grid = malloc(sizeof(*grid) * row);
for (int y = 0; y < row; ++y)
    grid[y] = malloc(sizeof(*grid[0]) * col);

然后记得释放所有这些数组。

在许多情况下,这并不是真正需要的,因此您可以创建一个 1D 数组,然后将其索引为 2D。例如array[y * width + x]

Table *grid = malloc(sizeof(*grid) * row * col);
for (y = 0; y < row; y++)           // assigns values to the table
{
    for (x = 0; x < col; x++)
    {
        grid[y * col + x].cellX = 1;      // all x-values will be 1
        grid[y * col + x].cellY = 2;      // all y-values will be 2
    }
}

你的结构也包含指针,但我真的不明白为什么,你从来没有分配过它们。只存储值。

typedef struct
{
    int cellX;
    int cellY;
} Table;

【讨论】:

  • 没错,我想让类型清楚,但最好只显示声明。
  • 旁白:sizeof(*grid) * row * colrow * col * sizeof(*grid) 有优势。后来的(int * int * size_t) 产品比第一个(size_t * int * int) 更容易溢出。
  • 在那张纸条上,我可能不会使用带符号的 int 作为用户输入开始,它不会导致问题中的问题,但在可能允许的情况下要记住另一个范围验证越界读/写。
猜你喜欢
  • 2012-05-07
  • 2015-03-15
  • 1970-01-01
  • 1970-01-01
  • 2015-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多