I’m writing a program in C. I’m using a dynamic array in my program, and am using a for loop to cycle through the items in the array. The problem I’m having, is that when I go to print the list to the screen (in the for loop), all previous items in the list are changed to the most recently created item. I don’t know what’s causing this. I have gone through the code numerous times in GDB, and I still can’t find what’s wrong.
/* 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;
If you could point me in the right direction, that would be much appreciated.
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_placesis checked after the first iteration of the loop body. Ifweap_Listhas 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
_tmpwere 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
_prefixvariable 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 plaintmpwould 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.