我正在尝试使用C语言中的结构和指针结构进行练习。我遇到了一个困扰我的问题。我已经设置了一个函数,它从指向结构的指针中获取3个值并返回一个浮点数。但是,在调用此函数时,它会修改原始结构的值,最终导致访问冲突和一些讨厌的字符反流。单步执行代码后,值就可以了,直到我返回函数的值。
这是我的结构:
struct product
{
int ID;
char name[MAXNAME];
char department[MAXDEPT];
float price;
int taxable;
int free_shipping_eligible;
};
typedef struct product Product;
功能原型:
Product * getInput(void);
float transactionTotal(const float price, const int taxable,
const int free_shipping);
void displayTransaction(const Product * inventory,
const float total_price);
主:
int main(void)
{
// Declare a pointer to a struct.
Product * invPoint = NULL;
float grand_total = 0.0;
// Get the value of the address of a struct.
invPoint = getInput();
// Use that address to get the total of a transaction.
grand_total = transactionTotal(invPoint->price, invPoint->taxable,
invPoint->free_shipping_eligible);
// Display product information and the transaction's total.
displayTransaction(invPoint, grand_total);
return EXIT_SUCCESS;
}
这是填充结构成员值的函数:
Product * getInput(void)
{
// Declare our struct and struct pointer variables.
Product inventory;
Product * fillInventory = NULL;
// Get user input.
printf("Please enter the product's ID.\n\t");
scanf("%d", &inventory.ID);
printf("Please enter the product's name.\n\t");
scanf("%s", &inventory.name);
printf("Please enter the product's price.\n\t");
scanf("%f", &inventory.price);
printf("Which department is the product located in?\n\t");
scanf("%s", &inventory.department);
printf("Is it taxable? 0 for no, 1 for yes.\n\t");
scanf("%d", &inventory.taxable);
printf("Is it free shipping eligible? 1 for no, 0 for yes.\n\t");
scanf("%d", &inventory.free_shipping_eligible);
fillInventory = &inventory;
// Return a pointer to our struct.
return fillInventory;
}
transactionTotal函数似乎是罪魁祸首。这是它的代码:
float transactionTotal(const float price, const int taxable,
const int free_shipping)
{
float total_price = 0.00;
float tax = (float)(taxable * TAX_RATE);
float shipping = (float)(free_shipping * SHIPPING_RATE);
total_price = price + price * tax + price * shipping;
return total_price;
}
在开始上述功能之前,我输入了以下值:
ID:232
名称:“咖啡”
部门:“食物”价格:8.99
应税:0
free_shipping_eligible:1
在transactionTotal函数之后:
ID:-858993460
名称:(奇怪的字符)
部门:(奇怪的人物)价格:9.88899994
应税:-858993460
free_shipping_eligible:14679252
答案 0 :(得分:7)
// Return a pointer to our struct.
return fillInventory;
}
您的结构对象在您的函数中声明,并且具有在函数返回后结束的生命周期。当函数返回并尝试访问它时,将丢弃结构对象,然后调用未定义的行为。将结构对象作为参数传递给函数,或使用malloc
分配其存储空间以解决问题。
答案 1 :(得分:1)
问题出在getInput
:
Product inventory;
Product * fillInventory = NULL;
....
fillInventory = &inventory;
// Return a pointer to our struct.
return fillInventory;
您将返回本地变量的地址。当函数返回时,该变量超出范围,导致undefined behavior。
您需要为此结构动态分配空间。
Product * getInput(void)
{
Product * fillInventory = malloc(sizeof Product);
...
然后调用者需要free
该结构:
int main(void)
{
// Declare a pointer to a struct.
Product * invPoint = NULL;
float grand_total = 0.0;
// Get the value of the address of a struct.
invPoint = getInput();
// Use that address to get the total of a transaction.
grand_total = transactionTotal(invPoint->price, invPoint->taxable,
invPoint->free_shipping_eligible);
// Display product information and the transaction's total.
displayTransaction(invPoint, grand_total);
free(invPoint); // free the memory
return EXIT_SUCCESS;
}