我试图像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 ***
}
}
}
为什么打印出无效指针错误?在我的平台上(Windows 8 + cygwin),它会打印实际的what()
返回值。这是否意味着我有UB?如果是这样,我的代码在哪里是UB?
一般来说,我该如何解决这个问题?我想要打印一个人类可读的what()
返回值。
答案 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;
}