【问题标题】:istream crash in while-switch loopistream 在 while-switch 循环中崩溃
【发布时间】:2012-06-19 07:11:45
【问题描述】:

我在 while 循环中有一个开关。在我三次调用选项 4 之后,程序在下次我输入决定在 switch 中进入哪种情况的 int 时崩溃。我不知道为什么会这样。 这是while循环的代码:

void Menu::start()
{
    Store st;
    int op=1,num,quantity;
    string name;
    while(op!=0)
    {
        cin>>op;
        try
        {
            switch(op)
            {
                    case 1:
            {
                cin>>num>>name;
                st.addProduct(num,name);
                break;
            }
            case 4:
                {
                    cin>>num>>quantity;
                    st.sellProduct(num,quantity);
                    break;
                }
            case 0:
                break;
            default:
                throw(exception("Unknown option, try again.\n"));
            } //end of switch
        } //end of try
//catches
    } //end of while
}

/*****************************************************************************
* function name: addProduct
* The Input: This Store, const& int num, const& string name
* The output: If product with given num doesn't exist in store, adds it to
* store.
* The Function operation: uses the products map.
*****************************************************************************/
void Store::addProduct( const int& num,const string& name )
{
    //if product doesn't exist in map, add it
    if(prods.find(num)==prods.end())
        prods.insert(pair<int,Product>(num,Product(num,name)));
    //otherwise issue an error
    else
        throw(AddProdException(num));
}

/*****************************************************************************
* function name: sellProduct
* The Input: This Store, const int& prodNum, const unsigned int& quantityBought
* The output: If product doesn't exist or quantityBought is more than 10 units
* more than quantity in stock, issues an error. Otherwise, sells the product
* and if needed, issues a shipment such that after the purchase the store will
* be left with 20 units.
* The Function operation: uses the products and orders map.
*****************************************************************************/
void Store::sellProduct( const int& prodNum, const unsigned int& quantityBought )
{
    if(prods.find(prodNum)!=prods.end())
    {
        Product& pr = prods.find(prodNum)->second;
        const int& signedQB=quantityBought, signedPQ=pr.getQuantity();
        if( signedPQ<signedQB-10 )
            //store can't supply product
            throw(BuyQuanException(prodNum,quantityBought));
        //make purchase
        else
        {
            //purchase only what left in stock
            if(signedPQ<signedQB )
            {
                //issue shipment
                Order order=Order(prodNum,20+quantityBought-pr.getQuantity());
                orders.insert(pair<int,Order>(order.getID(),order));
                //document order
                purchaseDocs.add(new Documentation(pr,quantityBought,
                    orders.find(order.getID())->second));
                //buy product
                pr.decreaseQuantity( pr.getQuantity() );
            }
            //purchase requested amount
            else
            {
                //buy product
                pr.decreaseQuantity( quantityBought );
                //document order
                purchaseDocs.add(new Documentation(pr,quantityBought));
            }
        } //else regarding making the purchase

    } //if regarding found the product
    //otherwise issue an error
    else
        throw(BuyProdException(prodNum));
}

3 次进入 case 4 后,(并且仅在 case 4 中,仅在 3 次后),它在下一次到达 cin>>op 时崩溃,在 istream 文件中。崩溃是指弹出以下错误消息:“Ex6.exe 中 0x4a34870c 处的未处理异常:0xC0000005:访问冲突。”欢迎帮助!

【问题讨论】:

  • 只是猜测,你没有使用 c++11,是吗?无论如何,你应该valgrind看看它。
  • “崩溃”是什么意思?此外,请在此处发布之前将您的代码减至最少,并为我们提供最少的可编译代码。您发布的代码包含大量我们不知道的内容,因此我们无法重现您的问题。
  • 更新问题。还有 Jonas,不使用 c++11。
  • 如果你没有扔任何东西,唯一可能的罪魁祸首是Store::sellProduct。你为什么不发布呢?
  • 更新问题以包含 sellProduct 和 addProduct。添加 1 个产品,将部分产品销售 2 次,然后选择下一个案例进入后发生错误。

标签: c++ istream


【解决方案1】:

这个:

const char* errStr=e.what();
cout<<errStr;
//errStr is a dynamically allocated string we don't need anymore <-----------
delete[] errStr;

这是一个糟糕的假设。 std::exception::what 返回的 const char* 不是动态分配的,它只是一个指向异常内部分配的字符串的指针。您不得删除该指针。您的代码中可能还有其他一些错误,但您应该修复它。

【讨论】:

  • 我明白你的意思,但只是在我的异常(ProductException)中,errStr 是动态分配的 - 所以我必须删除它以防止内存泄漏......不是吗?
  • 您应该提供该异常的定义。我假设你的异常继承了std::exception(这看起来合乎逻辑,因为你调用了ProductException::what())。
  • @Idan:在这种情况下,请确保您的异常是可复制的(并且在复制时可以正常工作)。
  • ybungalobill 是完全正确的。您应该给我们您的 ProductException 定义,否则我们无能为力。
  • mfontanini - 它确实继承自异常但会覆盖 what()。 ybungalobill - 我很确定你已经找到了问题 - 我的异常被复制得很浅,它会导致问题。谢谢! p.s.我有一个动态分配的指针的唯一原因是因为它不适用于非动态分配的指针。我已经更新了我的问题以包含异常定义。您知道如何实现 what() 而不必处理由动态分配引起的问题吗?
猜你喜欢
  • 2021-07-09
  • 1970-01-01
  • 2016-06-19
  • 1970-01-01
  • 1970-01-01
  • 2023-01-31
  • 1970-01-01
  • 2018-08-27
  • 1970-01-01
相关资源
最近更新 更多