C++ variable no longer exists
#include <exception>
#include <iostream>
#include <cstdio>
using namespace std;
class BaseException : exception {
public:
BaseException(const char* message) : message(message) {}
const char* getMessage() {
return message;
}
private:
const char* message;
};
void wrong() {
unsigned short int argumentCallCounter = 1;
/// @todo check why commented below does not work ?!
// char tmp[13 + sizeof(argumentCallCounter)];
/// @todo but this works
char* tmp = new char[13 + sizeof(argumentCallCounter)];
sprintf(tmp, "No %u argument", argumentCallCounter);
throw BaseException(tmp);
}
int main(int argc, char** argv) {
try {
wrong();
} catch (BaseException e) {
cout << e.getMessage() << endl;
}
return 0;
}
The code above works, but in comments, there is a code segment, that does not work.
char tmp[13 + sizeof(argumentCallCounter)];
I understand that it does not work because when the program leaves function wrong
the variable tmp no longer exists.
Can anybody help with this?
And also that decision that I write:
char* tmp = new char[13 + sizeof(argumentCallCounter)];
It's no good either, becaus开发者_如何学运维e when the program is complete, there is a memory leak, because nobody deletes tmp
I am usually throwing a std::runtime_exception initialized with a std::string.
http://www.cplusplus.com/reference/iostream/stringstream/ http://www.cplusplus.com/reference/std/stdexcept/runtime_error/
void wrong() {
unsigned short int argumentCallCounter = 1;
std::stringstream ss;
ss << "No " << argumentCallCounter << " argument";
throw std::runtime_error(ss.str());
}
//why commented below is not works
char tmp[13 + sizeof(argumentCallCounter)];
It would not work because tmp
is local to the function, and it not more exists once you exit from the function, but you're still trying to access it from main()
.
I would suggest you to use std::string
in BaseException
and everywhere else.
I would also suggest you to catch the exception by const
reference as:
catch (const BaseException & e)
// ^^^^^ note ^ note
EDIT:
Implement BaseException
as follows:
class BaseException : std::exception
{
public:
BaseException(std::string msg) : message(msg) {}
//override std::exception::what() virtual function
virtual const char* what() const throw()
{
return message.c_str();
}
private:
std::string message;
};
Use it as:
try
{
//some code that might throw BaseException
}
catch (const BaseException & e)
{
cout << "exception message : " << e.what() << endl;
}
EDIT:
And implement wrong()
as
void wrong() {
unsigned short int argumentCallCounter = 1;
std::stringstream ss;
ss << "No " << argumentCallCounter << " argument";
throw BaseException(tmp.str());
}
What do you mean by “not works”?
The BaseException
should copy the string it gets from the constructor, and make a local copy of it. Then, the wrong
function can deallocate it in any case.
And when you do that, the local tmp
array should work again.
精彩评论