在 C 中打印动态数组
我正在用 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;
如果您能指出正确的方向,我将不胜感激。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您在错误的时间增加了 num_places 。
更改
为
You increment num_places at the wrong time.
Change
to
一些快速的想法:
num_places
作为数组索引,将从0
开始。如果列表中只有零种或一种武器,此循环将严重失败。 (在循环体的第一次迭代之后检查条件i。如果
weap_List
有一个元素(位于索引0
),此循环将访问未分配的内存,并且不会在0
处打印武器。唯一应该容忍单索引数组的时候。当从头开始将大量 FORTRAN 代码移至 C 时,请使用零索引数组,正如 K&R 所希望的那样:)如果
_tmp
被声明为(weapon *) tmp = realloc(...)
,那么您就不需要(weapon *)
转换在下一行。小小的挑剔:在添加第 196609 个武器时,将尺寸加倍是相当昂贵的方法。考虑每次只增长八。 (我从你的名字猜测,你可能不会连续几周每秒添加一项。)
微小的挑剔:避免使用
_prefix
变量名,它们是为 C 运行时保留的环境。是的,几乎每个程序都使用它们,是的,我使用过它们,是的,这个可能是安全的:),但它们在技术上是保留的。一个简单的tmp
就足够了。更大的挑剔:您没有检查
realloc(3)
的返回值。它可能失败。您的应用程序应该尽可能优雅地处理失败。Some quick thoughts:
num_places
, being an array index, will start at0
. This loop will fail badly with only zero or one weapons in your list. (The conditioni < num_places
is checked after the first iteration of the loop body. Ifweap_List
has one element (at index0
), this loop will access memory that is not allocated and not print the weapon. Start array-handling loops at0
. The only times you should ever tolerate one-indexed arrays is when moving a huge amount of FORTRAN code to C; when starting from scratch, use zero-indexed arrays, as K&R intended. :)If
_tmp
were declared(weapon *) tmp = realloc(...)
, then you wouldn't need the(weapon *)
cast on the next line.Tiny nitpick: doubling the size is pretty expensive way to go when adding the 196609th weapon. Consider just growing by eight each time. (I'm guessing from your names that you're probably not going to be adding one item per second for weeks on end.)
Tiny nitpick: Avoid
_prefix
variable names, they are reserved for the C runtime environment. Yes, just about every program uses them, and yes, I've used them, and yes this one is probably safe :) but they are technically reserved. A plaintmp
would suffice.Larger nitpick: you're not checking the return value from
realloc(3)
. It can fail. Your application should handle failure as gracefully as possible.