动态内存分配在C中不起作用。

时间:2022-09-06 15:19:03

I'm trying to make a game that requires dynamically sized arrays in C but my code isn't working even though identical code works in another one of my programs.

我正在尝试做一个需要在C中动态调整数组大小的游戏,但是我的代码不能工作,即使相同的代码在我的另一个程序中工作。

Here are my #includes

这是我的#包括

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "SwinGame.h" //API for graphics, physics etc
#include <math.h>

Here are my typedefs for the relevant structs used:

以下是我用于相关结构的字体:

typedef struct position_data
{
  double x;
  double y;
} position_data;

typedef enum enemy_type_data {CIRCLE, TRIANGLE, SQUARE} enemy_type_data;

typedef struct enemy_data
{
  position_data location;
  enemy_type_data type;
  bitmap bmp;
  double health;
  double speed;
  int path_to;
} enemy_data;

typedef struct enemy_data_array
{
  int size;
  enemy_data *data;
} enemy_data_array;

Here is the function to add an element to the array:

下面是向数组中添加元素的函数:

void add_enemy(enemy_data_array *enemies)
{
  enemy_data *new_array;
  enemies->size++;
  new_array = (enemy_data *)realloc(enemies->data, sizeof(enemy_data) * enemies->size);
  if (new_array) //if realloc fails (ie out of memory) it will return null
  {
    enemies->data = new_array;
    // enemies->data[enemies->size - 1] = read_enemy_data();
    printf("Enemy added successfully!\n");
  }
  else
  {
    printf("FAILED. Out of Memory!\n");
    enemies->size--;
  }
}

And here is my function call and variable declaration in the main procedure:

这是我在主程序中的函数调用和变量声明:

int main()
{
  path_data my_path[41];
  enemy_data_array enemies;
  enemies.size = 0;
  add_enemy(&enemies);
}

Why isn't this working?

为什么这不是工作吗?

3 个解决方案

#1


6  

You invoked undefined behavior by passing indeterminate value enemies->data in uninitialized variable having automatic storage duration. Initialize it before using add_enemy().

通过在具有自动存储持续时间的未初始化变量中传递不确定值敌人——>数据来调用未定义的行为。在使用add_enemy()之前初始化它。

int main()
{
  path_data my_path[41];
  enemy_data_array enemies;
  enemies.size = 0;
  enemies.data = 0; /* add this line */
  add_enemy(&enemies);
}

0 is a null pointer constant and can safely be converted to pointer NULL. Unlike NULL, 0 will work without including any headers. Of course you can use enemies.data = NULL; with proper header included.

0是一个空指针常量,可以安全地转换为空指针。与NULL不同,0可以不包含任何header。当然你可以使用敌人。数据=零;通过适当的标题包括在内。

#2


3  

@2501's explanation is completely correct. Another solution is to change your implementation of add_enemy() to something like this:

@2501的解释完全正确。另一个解决方案是将add_enemy()的实现更改为以下内容:

void add_enemy(enemy_data_array *enemies)
{
  enemy_data *new_array;

  // check if size was non-zero
  if (enemies->size++)
  {
    new_array = (enemy_data *)realloc(enemies->data, sizeof(enemy_data) * enemies->size);
  }
  // start new allocation
  else
  {
    new_array = (enemy_data *)alloc(sizeof(enemy_data) * enemies->size);
  }

  if (new_array) //if (re)alloc fails (ie out of memory) it will return null
  {
    enemies->data = new_array;
    // enemies->data[enemies->size - 1] = read_enemy_data();
    printf("Enemy added successfully!\n");
  }
  else
  {
    printf("FAILED. Out of Memory!\n");
    enemies->size--;
  }
}

#3


2  

If fails because you haven't cleared the content of "enemies". Since it is a stack variable, it will contain whatever garbage data is on the stack.

如果因为没有清除“敌人”的内容而失败。由于它是一个堆栈变量,它将包含堆栈上的任何垃圾数据。

set enemies.data to NULL in the main function and try it again.

设置的敌人。数据在主函数中为NULL,再试一次。

#1


6  

You invoked undefined behavior by passing indeterminate value enemies->data in uninitialized variable having automatic storage duration. Initialize it before using add_enemy().

通过在具有自动存储持续时间的未初始化变量中传递不确定值敌人——>数据来调用未定义的行为。在使用add_enemy()之前初始化它。

int main()
{
  path_data my_path[41];
  enemy_data_array enemies;
  enemies.size = 0;
  enemies.data = 0; /* add this line */
  add_enemy(&enemies);
}

0 is a null pointer constant and can safely be converted to pointer NULL. Unlike NULL, 0 will work without including any headers. Of course you can use enemies.data = NULL; with proper header included.

0是一个空指针常量,可以安全地转换为空指针。与NULL不同,0可以不包含任何header。当然你可以使用敌人。数据=零;通过适当的标题包括在内。

#2


3  

@2501's explanation is completely correct. Another solution is to change your implementation of add_enemy() to something like this:

@2501的解释完全正确。另一个解决方案是将add_enemy()的实现更改为以下内容:

void add_enemy(enemy_data_array *enemies)
{
  enemy_data *new_array;

  // check if size was non-zero
  if (enemies->size++)
  {
    new_array = (enemy_data *)realloc(enemies->data, sizeof(enemy_data) * enemies->size);
  }
  // start new allocation
  else
  {
    new_array = (enemy_data *)alloc(sizeof(enemy_data) * enemies->size);
  }

  if (new_array) //if (re)alloc fails (ie out of memory) it will return null
  {
    enemies->data = new_array;
    // enemies->data[enemies->size - 1] = read_enemy_data();
    printf("Enemy added successfully!\n");
  }
  else
  {
    printf("FAILED. Out of Memory!\n");
    enemies->size--;
  }
}

#3


2  

If fails because you haven't cleared the content of "enemies". Since it is a stack variable, it will contain whatever garbage data is on the stack.

如果因为没有清除“敌人”的内容而失败。由于它是一个堆栈变量,它将包含堆栈上的任何垃圾数据。

set enemies.data to NULL in the main function and try it again.

设置的敌人。数据在主函数中为NULL,再试一次。