我正在尝试在C中制作一个需要动态大小的数组的游戏,但即使相同的代码在我的另一个程序中工作,我的代码也无法正常工作。
以下是我的#includes
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "SwinGame.h" //API for graphics, physics etc
#include <math.h>
以下是我使用的相关typedefs
的{{1}}:
structs
以下是向元素添加元素的功能:
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;
这是我在主程序中的函数调用和变量声明:
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--;
}
}
为什么这不起作用?
答案 0 :(得分:6)
您通过在具有自动存储持续时间的未初始化变量中传递不确定值enemies->data
来调用未定义行为。在使用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
是一个空指针常量,可以安全地转换为指针NULL
。与NULL
不同,0
无需包含任何标题即可使用。当然,您可以使用包含正确标头的enemies.data = NULL;
。
答案 1 :(得分:3)
@2501's explanation完全正确。另一种解决方案是将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--;
}
}
答案 2 :(得分:2)
如果因为你没有清除“敌人”的内容而失败。由于它是一个堆栈变量,它将包含堆栈中的任何垃圾数据。
在main函数中将enemies.data设置为NULL并再次尝试。