【问题标题】:std::out_of_range exception string won't print after compiling code with gcc使用 gcc 编译代码后,std::out_of_range 异常字符串不会打印
【发布时间】:2015-04-06 15:55:20
【问题描述】:

我正在尝试测试以下异常处理代码:

#include "Array_Template.h"
using namespace std;

int main()
{
    Array<int> intArr1;
    //attempt to use out-of-range subscript
    try{
        cout << "\nAttempt to assign 1000 to intArr1[6]" << endl;
        intArr1[6] = 1000;
    } //end try
    catch (const out_of_range &ex){
        cout << "An exception occurred: " << ex.what() << endl;
    } //end catch
    return 0;
} //end main

在我的 Array 类模板中:

#ifndef ARRAY_H
#define ARRAY_H

#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <stdexcept>

//forward declarations of friend functions as specializations of template
template<typename T> class Array;

template<typename T>
std::istream &operator>>(std::istream &, Array<T> &);
template<typename T>
std::ostream &operator<<(std::ostream &, const Array<T> &);

//Array class template
template<typename T>
class Array
{
    friend std::istream &operator>> <>(std::istream &, Array<T> &);
    friend std::ostream &operator<< <>(std::ostream &, const Array<T> &);
public:
    Array(int = 5); //default constructor of array size 5
    Array(const Array<T> &); //copy constructor
    ~Array(); //destructor
    int getSize() const; //return size of array
    const Array<T> &operator=(const Array<T> &); //overloaded assignment operator
    bool operator==(const Array<T> &) const; //overloaded equality operator
    bool operator!=(const Array<T> &r) const //overloaded inequality operator, inline definition
    {
        return !(*this == r); //invokes Array<T>::operator==
    }
    T &operator[](int); //overloaded subscript operator for non-const objects
    T operator[](int) const; //overloaded subscript for const objects
private:
    int size; //pointer-based array size
    T *arrPtr; //pointer to first element of array
}; //end class Array

template<typename T>
Array<T>::Array(int s)
    :size(s > 0 ? s : 5), arrPtr(new T[size])
{
    for (int i = 0; i < size; ++i)
        arrPtr[i] = 0;
} //end Array constructor

template<typename T>
//ref return creates a modifiable lvalue
T& Array<T>::operator[](int index)
{
    if (index < 0 || index >= size) //check if out of bounds
        throw std::out_of_range::out_of_range("index out of range");
    return arrPtr[index]; //ref return
} //end operator[]

template<typename T>
//const ref return creates an rvalue
T Array<T>::operator[](int index) const
{
    if (index < 0 || index >= size) //check if out of bounds
        throw std::out_of_range::out_of_range("index out of range");
    return arrPtr[index]; //returns copy of this element
} //end operator[]

#endif

程序在 Visual Studio 中编译并执行良好,显示正确的一行错误消息:

但是当我用 gcc 编译同一个程序并运行它时,我得到以下输出:

* `./arrays_template' 中的错误:free():无效大小:0x0000000001426030 * ======= 回溯:========= /lib64/libc.so.6(+0x7364f)[0x7fd7c2e3d64f] /lib64/libc.so.6(+0x78eae)[0x7fd7c2e42eae] /lib64/libc.so.6(+0x79b87)[0x7fd7c2e43b87] ./arrays_template[0x4011a1] ./arrays_template[0x400fc7] /lib64/libc.so.6(__libc_start_main+0xf5)[0x7fd7c2debbe5] ./arrays_template[0x400c29]

之后是冗长的内存映射跟踪。 有人可以解释这里到底发生了什么以及如何解决它吗?通过修复,我的意思是如何获得与 catch 块中指定的相同的错误消息。

【问题讨论】:

  • 显示默认构造函数定义。
  • 附带问题:为什么是T operator[](int) const 而不是const T&amp; operator[](int) const
  • @VladfromMoscow 编辑并添加了默认构造函数的定义。
  • @vsoftco 我实际上是通过参考我正在使用的 C++ 教科书来编写代码的。我收集以第二种方式编写代码更有效,因为该值不是作为副本返回而是作为 const ref?
  • @bastille77 确实如此。除非您将 const ref 返回到函数内的本地对象,否则它将起作用。在这种情况下,您最终会得到一个悬空引用(即使 const ref 绑定到临时对象,它们也只能在直接赋值中执行,例如const Foo&amp; foo = Foo();,而不是从函数返回本地对象时,其中多了一层间接性正在执行(临时被复制到调用者的堆栈中,然后后者就是你最终得到的)。

标签: c++ templates gcc exception-handling


【解决方案1】:

以下代码错误:

throw std::out_of_range::out_of_range("index out of range");
//       ^^^^^^^^^^^^^^

应该改写为:

throw std::out_of_range("index out of range");

调用constructorstd::out_of_range


还要确保修改operator[](int) const的返回类型。

【讨论】:

  • 也谢谢!如果弗拉德没有早点来,我会选择你的答案。
  • 哦,我一直在想我先发布答案
  • 我仔细检查过,看来你是对的。你的答案在 4 分钟前就来了。我想这是我的疏忽,我很抱歉。
  • 哦,不,您必须接受对您最有帮助的答案,而不是最早的答案。我只是想我应该对早期评论进行澄清。
  • Tbh 你的两个答案几乎相同,而且都很有用。我希望他们可以让您选择多个答案,有时当多个答案都一样好时,选择一个似乎没有意义。
【解决方案2】:

在两个运算符中更改此语句

throw std::out_of_range::out_of_range("index out of range");

throw std::out_of_range("index out of range");

【讨论】:

  • 工作就像一个魅力。我有一种感觉,这两条线可能是问题的原因。当我第一次编译代码时,我实际上正确地编写了该语句,但没有包含 &lt;stdexcept&gt; 标头(我猜是使用 MSVS 的副作用,因为代码编译不受那里缺少的标头的影响)。结果,gcc 抛出错误 ‘out_of_range’ is not a member of ‘std’。所以我去 cplusplus.com 上查找它的条目以查看它的位置,但误解了应该如何应用范围。无论如何,非常感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 2015-10-09
  • 2021-08-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多