【问题标题】:In C, returning a float when sending pointer-to-struct values to a function changes the values of the struct在 C 中,将指向结构的指针值发送到函数时返回浮点数会更改结构的值
【发布时间】:2015-12-07 20:35:19
【问题描述】:

我正在尝试在 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

【问题讨论】:

  • 您的getInput 函数返回inventory 的地址,即使函数返回时它已不存在。

标签: c function pointers struct


【解决方案1】:
    // Return a pointer to our struct.
    return fillInventory;
}

您的结构对象在您的函数中声明,并且其生命周期在您的函数返回后结束。当您的函数返回并尝试访问它之后调用未定义的行为时,结构对象将被丢弃。将您的结构对象作为参数传递给函数或使用malloc 分配其存储空间以解决您的问题。

【讨论】:

    【解决方案2】:

    问题出在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;
    }
    

    【讨论】:

    • invPoint 可能只是一个存在于main() 生命周期中的结构。完全可以避免malloc()/free() 调用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多