我一直在努力让这个功能正常工作。这是作业:
添加:请求零件名称,价格和数量。将信息保存到动态分配的结构数组中。您可以一次为最多3个结构分配空间。您需要根据需要动态创建更多内存。使用此结构(如果需要,可以使用typedef):
到目前为止,我的代码是
typedef struct {
char* name;
float price;
int quantity;
}part;
void add(part *item, int *part_count)
{
//char temp[100];
if (!item){
item = malloc(sizeof(part)*3);
}
else{
item = realloc(item, sizeof(part) * ((*part_count*3) + 1));
}
item[*part_count].name = malloc(sizeof(char)*64); // max of 64 characters
printf("Please enter item name: \n");
//fgets(temp, strlen(temp), stdin);
//sscanf(temp, "%s", item[*part_count].name);
scanf("%64s", item[*part_count].name);
printf("Please enter item price: \n");
//fgets(temp, strlen(temp), stdin);
//sscanf(temp, "%f", &item[*part_count].price);
scanf("%f", &item[*part_count].price);
printf("Please enter item quantity: \n");
//fgets(temp, strlen(temp), stdin);
//sscanf(temp, "%d", &item[*part_count].quantity);
scanf("%d", &item[*part_count].quantity);
*part_count = *part_count+ 1;
}
我曾尝试使用fgets()
和sscanf()
获取输入,但使用该代码时,它永远不允许用户输入数据然后结束该功能。
我认为问题在于我的内存分配,因为当我尝试对数组执行任何操作时会出现分段错误,例如打印内容。
答案 0 :(得分:1)
据推测,第一次调用add()时,item将为NULL,并且您将进行初始分配;后续调用realloc,以便数组大小是所需大小的3倍(我认为这不是你真正想要的)。
但是匹配项的参数不会因调用add()而改变,所以它保持为NULL,并且每次调用add()就好像它是初始调用一样,为3个结构分配空间(当您添加第4个结构时,这将是一个问题。)
您可以将项目设为**部分,并在当前使用部分的任何地方使用*部分,以便保留指针的新值(您将传递*部分的地址作为参数)。或者使用item的新值作为函数的返回值,这是一个更清洁的恕我直言。 (这是参考参数派上用场的地方,但C没有这样的东西。)
答案 1 :(得分:1)
您的功能有一个不可能的界面。它接受part *
指针。该指针按值进入函数。在您malloc
或realloc
来电中分配给它的功能中。但调用者不会看到此更新值。当函数返回时,您分配的内存已泄漏,调用者具有原始指针值(可能为null)。
此外,最好使用结构封装动态数组。你有这个“部件计数”变量,它本身就是松散的,必须与数组一起传递到任何地方以跟踪它的大小。如何将它们包装在一起:
typedef struct part_list {
struct part *part;
int count;
} part_list;
现在有一个初始化空零件清单的功能。每个想要使用其他part_list
函数的人都必须调用此。
void part_list_init(part_list *pl)
{
pl->part = 0;
pl->count = 0;
}
然后编写你的功能来添加部件。
int part_list_add(part_list *pl)
{
part_list *p;
int index = pl->count++; /* increment count, keep old value */
/* realloc accepts a null pointer and then behaves like malloc */
p = realloc(pl->part, sizeof *pl->part * pl->count);
if (p == 0)
return 0; /* failed to allocate/extend array */
p1->part = p;
if ((pl->part[index].name = malloc(64)) == 0) {
pl->count = index; /* roll back the count: we didn't really allocate this part */
return 0;
}
/* your code, updated with pl-> access */
printf("Please enter item name: \n");
scanf("%63s", pl->part[index].name); /* 63s not 64s!!! One byte for NUL char! */
printf("Please enter item price: \n");
scanf("%f", &pl->part[index].price); /* check the return value of scanf!!! */
printf("Please enter item quantity: \n");
scanf("%d", &pl->part[index].quantity);
return 1; /* 1 means success */
}