【问题标题】:Weird behavior with storing 2d array?存储二维数组的奇怪行为?
【发布时间】:2021-08-23 09:48:47
【问题描述】:

我已经包含了下面的代码,但总而言之,createMonster() 函数初始化 struct monster 字段,然后返回 struct 指针。 **readMonster() 函数应该从 input.txt 文件中读取信息并返回一个 createMonster() 指针数组。例如:monsterList[i] = createMonster(x ,y ,z)。重申一下,createMonster() 保存单个怪物的数据,并且 **readMonsters 返回一个包含其 createMonster 数据的怪物列表

问题是,当我使用第一个 for 循环循环并用 createMonster() 数据填充 monsterList[I],然后将其打印到屏幕上时,它可以完美运行。然而,创建第二个只打印 MonsterList[I] 的 for 循环会在屏幕上打印奇怪的东西。唯一正确打印的是 int population 字段。这是下面的代码。

// omitting failed malloc checks for simplicity. Assume no mallocs failed.
#define BUFFERSIZE 50

typedef struct monster
{
   char *name;
   char *element;
   int population;
} monster; // An index

monster *createMonster(char *name, char *element, int population)
{
  // Sizeof(struct monster) for clarification.
  monster *monster = malloc(sizeof(struct monster));

  // Allocating memory for struct monster fields
  monster->name = malloc(sizeof(char) * strlen(name) + 1); // +1 null sentinel

  monster->element = malloc(sizeof(char) * strlen(element) + 1);

  // Initalizing fields based on function input parameters
  monster->name = name;
  monster->element = element;
  monster->population = population;

  // Return struct pointer
  return monster;
}

monster **readMonsters(FILE *ifp, int *monsterCount)
{
  // Initializing array of struct monster pointers
  monster **monsterList = NULL;
  // Buffer to store monster name and monster element
  char name_buffer[BUFFERSIZE], element_buffer[BUFFERSIZE];
  // Buffer to store amount of monsters in file
  int num_monsters = 0;
  // Buffer to store monstor population
  int population;
  // Iterative variable
  int i;

  // making monsterCount the address of num_monsters
  monsterCount = &num_monsters;

  // alloating monsterList and
  // simultanenously scaning the value of monsters from the file into the address of num_monsters,
  // which is monsterCount
  monsterList = malloc(sizeof(int *) * (fscanf(ifp, "%d", monsterCount)) + 1);

  // File parsing. Skipping a string based on known input.txt file structure
  fscanf(ifp, "%*s");

  // storing file information into the monsters' individual monster pointer.
  // using num_monsters for clarification and to avoid segmentation faulting

  /*  These two for loops are the issue. The first for loop prints everything to
   the screen correctly. Therefore, in this for loop, monsterList[I] holds all the
   correct createMonster() data. 
  The second for loop should just print the same information to the screen, 
  but it doesn't. What is going on with malloc?
   */

    for (i = 0; i < num_monsters; i++)
    {
      fscanf(ifp,"%s %s %d", name_buffer, element_buffer, &population);
      monsterList[i] = createMonster(name_buffer, element_buffer, population);
      // prints correctly
      printf("\n monsterList[%d]->name: %s, ->element: %s, ->population: %d\n", i, monsterList[i]->name, monsterList[i]->element, monsterList[i]->population);
    }

    for (i = 0; i < num_monsters; i++)
    {
      // does not print correctly
      printf("\n monsterList[%d]->name: %s, ->element: %s, ->population: %d\n", i, monsterList[i]->name, monsterList[i]->element, monsterList[i]->population);
    }

    return monsterList;
  }

这是打印到屏幕上的内容:

//这些都是正确的

monsterList[0]->名称:StAugustine,->元素:草,->人口:12

monsterList[1]->名称:结缕草,->元素:草,->人口:8

monsterList[2]->名称:全麦,->元素:面包,->人口:6

monsterList[3]->名称:MultiGrain,->元素:面包,->人口:10

monsterList[4]->名称:黑麦,->元素:面包,->人口:10

monsterList[5]->名称:肉桂,->元素:香料,->人口:5

monsterList[6]->名称:胡椒,->元素:香料,->人口:10

monsterList[7]->名称:南瓜,->元素:香料,->人口:30

//(第二个for循环)这些都不正确,除了来自单元格1-7的人口

monsterList[0]->名称:pʛ??,->元素:pʛ??,->人口:-641705424

monsterList[1]->名称:南瓜,->元素:香料,->人口:8

monsterList[2]->名称:南瓜,->元素:香料,->人口:6

monsterList[3]->名称:南瓜,->元素:香料,->人口:10

monsterList[4]->名称:南瓜,->元素:香料,->人口:10

monsterList[5]->名称:南瓜,->元素:香料,->人口:5

monsterList[6]->名称:南瓜,->元素:香料,->人口:10

monsterList[7]->名称:南瓜,->元素:香料,->人口:30

对任何格式错误表示歉意。

【问题讨论】:

  • 您正在用monster-&gt;name = malloc(...) 覆盖内存分配,然后用monster-&gt;element 覆盖monster-&gt;name = name; 同上。请使用strcpy() 复制字符串。但是monster-&gt;population = population; 可以。
  • monsterList = malloc(sizeof(int *) * (fscanf(ifp, "%d", monsterCount)) + 1); fscanf 返回扫描项目的数量,而不是其中任何一个的值。在这种情况下,如果转换成功,则返回值为 1 并且没有分配足够的内存。没有充分的理由不是两个步骤。读取该值,也许对其进行一些验证,然后使用该值进行分配。更具可读性,更易于在调试器中查看,并且出错的可能性更低。
  • 刚刚尝试使用 strcpy(monster->name, name) 并且它可以工作,除了数组 [0] 和数组 [1]。他们仍然被破坏。 @WeatherVane
  • @RetiredNinja 你指的是readMonster函数中最初的monsterList分配吗?
  • 这里:monsterList = malloc(sizeof(int *) * (fscanf(ifp, "%d", monsterCount)) + 1); fscanf() 的返回值与所需的内存量无关。 sizeof(int*) 也没有。应该是malloc(sizeof(monster*) * num_monsters)

标签: c multidimensional-array malloc


【解决方案1】:

行:monsterList = malloc(sizeof(int *) * (fscanf(ifp, "%d", monsterCount)) + 1);是问题所在。 修复:

先使用 fscanf 读取怪物数量,然后使用该值为 monsterList 分配内存

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-11
    • 1970-01-01
    • 1970-01-01
    • 2015-03-18
    • 2023-04-06
    • 2015-03-02
    • 2017-05-26
    相关资源
    最近更新 更多