我正在用C语言编写程序。我在程序中使用动态数组,并使用for循环遍历数组中的项目。我遇到的问题是,当我将列表打印到屏幕上时(在for循环中),列表中的所有先前项目都将更改为最近创建的项目。我不知道是什么原因造成的。我在GDB中多次浏览过代码,但我仍然无法找到错误。
/* For Loop, Displays Weapon List */
for (i = 1; i < num_places; i++)
{
printf("%d. \n",i);
printf("Des: %s \n\n",weap_List[i].description);
}
/* Add function, adds a weapon to the list */
int Add_weap(weapon new_weap)
{
if (num_places == num_allocated)
{
if (num_allocated == 0)
num_allocated = 3;
else
num_allocated *= 2;
void *_tmp = realloc(weap_List, (num_allocated * sizeof(weapon)));
weap_List = (weapon*)_tmp;
}
num_places++;
weap_List[num_places] = new_weap;
return num_places;
}
/* Code that invokes the function, adding the weapon to the list */
printf("Adding new weapon \n");
weapon temp;
printf("Please enter the description of this new weapon. \n");
scanf("%s",weap.description);
Add_weap(temp);
/* Weapon structure */
typedef struct {
char* description;
} weapon;
如果你能指出我正确的方向,那将非常感激。
答案 0 :(得分:2)
您在错误的时间增加num_places。
更改
num_places++;
weap_List[num_places] = new_weap;
到
weap_List[num_places++] = new_weap;
答案 1 :(得分:1)
一些敏捷的想法:
作为数组索引的for (i = 1; i < num_places; i++) {
num_places
将从0
开始。如果列表中只有零个或一个武器,此循环将严重失败。 (在循环体的第一次迭代之后检查条件i < num_places
。如果weap_List
有一个元素(在索引0
),这个循环将访问未分配的内存和不打印武器。在0
启动数组处理循环。你应该只容忍一个索引数组的唯一时间是移动大量的FORTRAN代码到C;当从头开始时,使用零索引数组,如K&amp; R所预期的那样。:)
void *_tmp = realloc(weap_List, (num_allocated * sizeof(weapon))); weap_List = (weapon*)_tmp;
如果_tmp
被宣布为(weapon *) tmp = realloc(...)
,则您不需要在下一行(weapon *)
投射。
微小的挑剔:在添加196609号武器时,将尺寸加倍是相当昂贵的方法。考虑每次只增加8。 (我猜你的名字,你可能不会在几个星期内每秒增加一件物品。)
Tiny nitpick:避免使用_prefix
变量名,它们是为C运行时环境保留的。是的,几乎每个程序都使用它们,是的,我使用它们,是的,这个可能是安全的:)但它们在技术上是保留的。简单的tmp
就足够了。
更大的挑剔:你没有检查realloc(3)
的返回值。它可以失败。您的应用程序应尽可能优雅地处理故障。