从std :: exception派生的类会在what()上抛出无效指针错误

时间:2015-07-01 12:50:23

标签: c++ exception

我试图像std::exception一样派生出来:

class bad_number : public std::exception
{
public:
    bad_number(const char*);
    virtual const char* what() const noexcept;
private:
    const char* num;
};

bad_number::bad_number(const char * num) : num(num){ }
const char* bad_number::what() const noexcept
{
    std::string str;
    str.append("Invalid number format:");
    str.append(num);
    char* result = new char[str.size()];
    strcpy(result, str.c_str());
    return result;
}

//The function that uses the exception
long double convert(const char *str)
{
    char *endptr;
    double result = strtold(str, &endptr);
    if (*endptr != '\0')
        throw bad_number(str);
    return result;
}

主要功能又如下:

int main(int argc, char ** argv)
{
    std::vector<long double> vect;
    for(int i = 1; i < argc; i++)
    {
        try{
            vect.push_back(convert(argv[i]));
        } catch (bad_number& e){
            std::cout << e.what() << std::endl;  //free(): 
                             //invalid pointer: 0x000000000131bc40 ***
        }
    }
}

DEMO

为什么打印出无效指针错误?在我的平台上(Windows 8 + cygwin),它会打印实际的what()返回值。这是否意味着我有UB?如果是这样,我的代码在哪里是UB?

一般来说,我该如何解决这个问题?我想要打印一个人类可读的what()返回值。

2 个答案:

答案 0 :(得分:4)

std::string::size()返回字符串中的字符数,不包括空终止符。因此,result只有一个char太短,strcpy会写过它。

此外,每次调用char时动态分配新的what()数组都是一个坏主意。 what()被声明为noexcept,即使new 可能投掷,也会使情况变得更糟。

更好地在异常的构造函数中构造std::string,将其存储为成员变量,然后返回其c_str()

答案 1 :(得分:0)

修改下面这样的功能代码

const char* bad_number::what() const noexcept
{
    std::string str;
    str.append("Invalid number format:");
    str.append(num);
    char* result = new char[str.size()+1];
    strcpy(result, str.c_str());
    return result;
}