【问题标题】:Templated function is crashing upon returning values模板化函数在返回值时崩溃
【发布时间】:2014-09-21 21:15:50
【问题描述】:

我创建了一个名为 Map 的双链表模板化类,它接收一个名为 MapItem 的结构,该结构具有两个模板化变量(键和值),并对它们执行某些功能。到目前为止,我的所有函数都可以工作,除了这个名为 get 的函数,它接受一个键和布尔变量作为参数,或者:返回与键关联的值,如果找到键,则将布尔变量设置为 true,或者不返回任何东西并将布尔变量设置为false。当我在 main 中调用此函数时,它不断崩溃,我的思绪被错误的地方所困扰。让我知道你们的想法!

template <class keyType, class valueType>
valueType Map<keyType, valueType>::get(keyType key, bool & success) const
{
    if(sizeList == 0) //if the list is empty, set success to false since there is nothing to return
        success = false;
    else if(sizeList == 1) //if one item, check it to see if it's the one we're looking for
    {
        if(head->key == key) //if it is the item, return the value
        {
            success = true;
            return head->value;
        }
        else
            success = false;
    }
    else //if the size of the list is greater than 1, increment through it
    {
        int i = 1; 
        struct MapItem<keyType, valueType> *temp = head; //store head in temp as the first item to check and increment through all the items

        while(i <= sizeList)
        {
            if(temp->key == key) //if we found it
            {
                success = true;
                return temp->value;
            }

            temp = temp->next; //get the next item
            i++;
        }
    }
    success = false;
}

这是我所说的 MapItem 结构体,它在 Map 类中用于存储项目:

template <class keyType, class valueType>
struct MapItem
{
  keyType key;
  valueType value;
  MapItem<keyType, valueType> *prev, *next;
};

是的,我知道函数 get 没有返回语句,如果它实际上没有找到密钥,但我们的教授说它应该没问题,但此时我开始不这么想了。可以实现一个错误异常来处理这个吗?谢谢。

【问题讨论】:

  • 侧面观察:为什么不返回 std::tuple 而不是使用那个输出引用参数?
  • 你必须返回一些东西,否则程序是未定义的。你的编译器应该警告过你。
  • 感谢您的回复。什么是标准:元组?在这种情况下如何使用错误处理?
  • 我当然希望您只是误解了老师的意思。否则,我很抱歉。

标签: c++ pointers memory get crash


【解决方案1】:

您的函数在失败时不返回值。这是一个错误:

6.6.3 返回语句[stmt.return]

[...]
从函数的末尾流出相当于没有值的返回;这导致未定义 值返回函数中的行为。

侧面观察:

考虑使用std::tuple&lt;bool, valueType&gt;,而不是返回带有输出参数的错误成功。

如果在失败时构造主返回值是不可接受的,请获取std::experimental::optional 的预发布版本(有时会在 TC 中遵循 C++14)。

Boost 实现已经很好了:http://www.boost.org/doc/libs/master/libs/optional/doc/html/index.html

第三种选择是在失败时抛出异常。

【讨论】:

  • 感谢您的回复!您是否知道在我可以阅读的失败时抛出异常的任何好的链接?谢谢。
  • 任何关于 C++ 的教程都应该这样做。试试 C++ book-list 或 SO 上的 C++ tag-wiki。
  • 所以我尝试在函数中添加一个异常,但程序仍然不断崩溃,你能给我一个代码示例吗?谢谢。
  • 您的程序是否在最大警告时编译而没有任何警告?
猜你喜欢
  • 1970-01-01
  • 2016-08-03
  • 1970-01-01
  • 2016-01-09
  • 1970-01-01
  • 1970-01-01
  • 2017-04-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多