For some reason the program exits when executed while testing the handling of an exception. This is the class im using as the exception recipient
#ifndef _BADALLOC
#define _BADALLOC
#include <cstring>
using namespace std;
class badalloc{
private:
char* Message;
double Number;
public:
explicit badalloc(char* M="Error",const int & N=0) {strcpy(Message,M); Number=N;}
char* what () const {return Message;}
};
#endif
this is the function member of another class that generates the exception
void ContoCorrente::Prelievo ( const double & P) throw ( badalloc )
{
if(P>0)
{
throw (badalloc ("ERROR 111XX",P));
} ...
test main :
try
{
c2.Prelievo(20);
}
catch ( badalloc e)
{
cout<<e.what()<<endl;
}
output:
Process exited after 1.276 seconds with return value 3221225477
Press any key to continue . . .
i tried defining the badalloc object to throw as "const" but to no use. any ideas?
Very simple, you are copying to an uninitialised pointer Message in your badalloc class.
You'd get this error just by constructing a badalloc object. This has nothing to do with exceptions.
EDIT
Here's a possible solution, using std::string to avoid the pointer problems.
#ifndef _BADALLOC
#define _BADALLOC
#include <string>
class badalloc{
private:
std::string Message;
double Number;
public:
explicit badalloc(const char* M="Error",const int & N=0) : Message(M), Number(N) {}
const char* what () const {return Message.c_str();}
};
#endif
Related
i am making a program and decided to make my own exceptions so i wrote the following header-only file:
#ifndef ARGUMENT_EXCEPTIONS
#define ARGUMENT_EXCEPTIONS
#include <exception>
namespace AAerr {
class ArgumentException : public std::exception {
private:
const char* msg;
static constexpr char* funcName = (char*)"ArgumentException";
public:
ArgumentException(const char* msg_) {
msg = msg_;
}
const char* getMessage() {
return msg;
}
virtual const char* what() const throw() {
return funcName;
}
};
class WrongReturnType : public ArgumentException {
private:
const char* msg = "Wrong Type";
char requestedType;
char ofType;
static constexpr char* funcName = (char*)"WrongReturnType";
public:
WrongReturnType(const char requested, const char is) : ArgumentException(msg) {
requestedType = requested;
ofType = is;
}
char get_requested_type() {
return requestedType;
}
char get_of_type() {
return ofType;
}
virtual const char* what() {
return funcName;
}
};
}
#endif // ARGUMENT_EXCEPTIONS
and when i tried to throw and catch one of them in my program it never caught anything:
#include "exception_header_file.hpp" // the name of the header file
#include <iostream>
int main() {
try {
throw AAerr::ArgumentException("TEST");
} catch (AAerr::ArgumentException& exc) {
std::cout << "CAUGHT EXCEPTION" << std::endl; // never executed
}
}
and then i made a second file (just to figure out where the problem is):
#include <iostream>
#include <exception>
namespace AAerr {
class Exc : public std::exception {
private:
const char* msg;
static constexpr char* funcName = (char*)"TEST FUNC";
public:
Exc(const char* msg_) {
msg = msg_;
}
const char* getMessage() {
return msg;
}
virtual const char* what() {
return funcName;
}
};
class Exc2 : public Exc {
private:
int line;
static constexpr char* funcName = (char*)"FUNCTION";
public:
Exc2(const char* msg_, int line_) : Exc(msg_) {line = line_;}
virtual const char* what() {
return funcName;
}
};
};
int main() {
try {
throw Exc2("TEST", 5);
} catch (AAerr::Exc& exc) {
std::cout << "CAUGHT EXCEPTION" << std::endl; // works fine
}
}
can someone help me find where the problem is?? i can't find any difference between these 2.
compiler: g++(gcc)
platform: ubuntu(linux)
EDIT:
i managed to fix the problem.
it was on the on the linker(ld).
i changed my Makefile to build the whole project instead of making and then linking everything.
what i mean is, i did:
build:
g++ program_part1.cpp program_part2.cpp program_part3.cpp -o example.elf
instead of:
build: part1.o part2.o part3.o
g++ part1.o part2.o part3.o -o output.elf
part1.o: program_part1.cpp program_part1.hpp
g++ -c program_part1.cpp -o part1.o
...
...
I suspect that problem is in "main program", see OP comment in other answer:
yeah i tried and it's the same thing. it doesn't work on my main program, but works fine on the testing program i have – user898238409
If "main program" is using dynamic libraries and exception are defined as "header only", this can lead to situation that RTTI (Run Time Type Information) is generated for this class multiple times. One for each include for dynamic library and main executable where this header file is included.
For example this can go like this:
dynamic library creates instance of class AAerr::ArgumentException using RTTI generated for that library when exception and throws this as exception.
main executable is trying catch that exception using RTTI which was build for that executable.
Since those two RTTI do not match to each other catch statement can't notice that expected exception is thrown.
Proper fix for that is to drop "header only" exceptions so all virtual methods should be defined in cpp file. This will lead to well defined association with specific library. As a result only one RTTI will be present for ArgumentException and WrongReturnType.
Have you tried catching std::exception instead of the exception class?
Like this:
try{
throw AAerr::Argument exception("Test");
} catch (std::exception exc) {
std::cout << "HEY" << std::endl;
}
I tried to create my custom exception class for printing helpful message's sakes:
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <vector>
#include <sstream>
#include <cstdlib>
class invalid_input_exception : public std::exception
{
private:
const char* input;
public:
invalid_input_exception(const char *);
const char* what() const noexcept;
};
invalid_input_exception::invalid_input_exception(const char * input) : input(input) { }
const char * invalid_input_exception::what() const noexcept
{
std::string message;
message.append("Occured on: ")
.append(input);
return message.c_str();
}
int main(int argc, char ** argv)
{
const char* str = "Aaaaa";
throw invalid_input_exception(str);
}
But it doesn't excatly work because after throwing the instance of invalid_input_exception the what() message was actually empty.
DEMO
What was wrong?
return message.c_str();
message is local to the function, and you're returning a pointer to its internal buffer. Undefined behaviour ensues.
message is a local variable, which has been destroyed when out of invalid_input_exception::what(), and the pointer returned by string::c_str() became invalid too.
You need to deep copy the content here, and might store it to the member variable input. And pay attention to the allocation and deallocation of it.
Two main problems here:
message is a local variable and will go out of scope at the end of what - thus the returned pointer is not pointing to valid string conent.
The exception class MUST make a copy of the passed message since you cannot expect the source of the message to be still valid at the point the exception will be catched.
You could go for
#include <exception>
#include <string>
class invalid_input_exception : public std::exception
{
private:
std::string input;
public:
invalid_input_exception(const char *in) : input(in)
{
input = "Occured on: " + input;
}
const char* what() const noexcept
{
return input.c_str();
}
};
or you use runtime_error as a base which has a message-copy-constructor and what:
#include <stdexcept>
#include <string>
class invalid_input_exception : public std::runtime_error
{
public:
invalid_input_exception(const char *in) :
runtime_error(("Occured on" + std::string(in)).c_str())
{ }
const char* what() const noexcept
{
return runtime_error::what();
}
};
Consider this implementation instead:
#include <stdexcept>
class invalid_input_exception : public std::runtime_error
{
public:
invalid_input_exception(const std::string& msg): std::runtime_error{ msg }{}
};
This is better for the following reasons:
The what() member function is already implemented by std::runtime_error, to work with a std::string.
Your exception class is a std::runtime_error (inheriting from std::exception dirrectly only makes sense when it is imposed by the module's design, or when you need an exception offering another data format (that is, different than a text message). Alternately, you could inherit from std::logic_error.
The class manages it's resources correctly, through the use of std::string.
Is it possible to capture and print name of the function which initialized a class object? What I want is something like this:
class MyException: public std::exception
{
public:
MyException(const std::string message, const std::string caller = __func__)
: _caller(caller),
_msg(message)
{
...
}
std::string what(void); // prints messaged along with the caller
private:
...
}
In the above class MyException I want the caller to capture the function name where an object was instantiated so that user is warned of which function threw. I can always do
...
throw MyException(message, __func__);
...
while removing the default __func__. But then I am doing this trivial thing every time I instantiate an MyException object.
Is there a better way to instruct user exactly which function throws?
Thanks in advance,
Nikhil
If I wanted to provide automatic context for my exceptions I'd do it like this:
#include <iostream>
#include <stdexcept>
#include <string>
struct context_info {
explicit context_info(std::string function)
: _function { std::move(function) }
{}
// perhaps the context info will increase later to include class and instance?
friend std::string to_string(const context_info& ci)
{
return ci._function;
}
private:
std::string _function;
};
struct my_exception : std::runtime_error
{
my_exception(const std::string& message)
: std::runtime_error(message)
{}
my_exception(context_info context, const std::string& message)
: my_exception(message + " called from " + to_string(context))
{}
// everything else already taken care of for you
};
#if defined(NDEBUG)
#define THROW_WITH_CONTEXT(TYPE, ...) throw TYPE(__VA_ARGS__)
#else
#define THROW_WITH_CONTEXT(TYPE, ...) throw TYPE(context_info(__func__), __VA_ARGS__)
#endif
using namespace std;
void do_foo()
try {
THROW_WITH_CONTEXT(my_exception, "foo failure");
}
catch(const exception& e) {
cout << e.what() << endl;
}
int main() {
// your code goes here
try {
do_foo();
THROW_WITH_CONTEXT(my_exception, "error");
}
catch(const exception& e) {
cout << e.what() << endl;
}
return 0;
}
expected output:
foo failure called from do_foo
error called from main
However, neat as this is it's probably not what you should really be doing as it won't provide you with enough context in a large complex program.
have a look at the documentation for std::throw_with_nested etc. You can catch an exception at each stage of the call stack and re-throw it with additional context information. This is much more useful.
http://en.cppreference.com/w/cpp/error/throw_with_nested
i've done a program. Unfortunately when trying to build it i got an error in function: undefined reference to `RzymArabException::RzymArabException(std::string).
When i was throwing a simple class like class Rzym{}; there was no errors. But when i created a class with some kind data(constructors and messages inside it doesnt work) I would be grateful if u could point where the mistake is.
#include <iostream>
#include <string>
using namespace std;
class RzymArabException{ //wyjatki
private:
string message;
int pozazakres;
public:
RzymArabException(string message);
RzymArabException(int pozazakres);
string getMessage(){return message;};
};
class RzymArab {
private:
static string rzym[13]; //konwersja z arabskich na rzymskie
static int arab[13];
static char rzymskie[7];
static int arabskie[7]; //konwersja z rzymskich na arabskie
public:
static int rzym2arab(string);
static string arab2rzym(int);
};
string RzymArab::rzym[13] = {"I","IV","V","IX","X","XL","L","XC","C","CD","D","CM","M"};
int RzymArab::arab[13] = {1,4,5,9,10,40,50,90,100,400,500,900,1000};
int RzymArab::arabskie[7] = {1000,500,100,50,10,5,1};
char RzymArab::rzymskie[7] = {'M','D','C','L','X','V','I'};
string RzymArab::arab2rzym(int x){
string s="";
if(x<1 || x>3999)
throw RzymArabException("Podana liczba w zapisie arabskim nie nalezy do dozwolonego przedzialu:(1..3999)");
else{
int i=12;
while(x>=1){
if(x>=arab[i]){
x-=arab[i];
s=s+rzym[i];
}
else
i-=1;
}
}
return s;
}
You need to provide definitions for your exception class methods, to link properly:
class RzymArabException{ //wyjatki
private:
string message;
int pozazakres;
public:
// Note the changes for the constructor methods!
RzymArabException(string message_) : message(message_) {}
RzymArabException(int pozazakres_) : pozazakres(pozazakres_) {}
string getMessage(){return message;}
};
Also I would recommend to derive any class used as exception to derive from std::exception:
class RzymArabException : public std::exception {
private:
string message;
int pozazakres;
public:
// ...
// Instead of getMessage() provide the what() method
virtual const char* what() const { return message.c_str(); }
};
This ensures that any standard compliant code will be able to catch your exception without having to use catch(...).
It's self-explanatory. You did not define that constructor; you only declared it.
I'm trying to implement a priority queue using a linked list, but I'm having issues with try/catch. Here are the relevant parts of the priority queue header file:
#ifndef PRIORITYQUEUELINKED_H
#define PRIORITYQUEUELINKED_H
#include "RuntimeException.h"
#include <list>
using namespace std;
template <typename E, typename C> // uses data type and some total order relation
class PriorityQueueLinked {
// code for PriorityQueueLinked
class EmptyPriorityQueueException : public RuntimeException {
public:
EmptyPriorityQueueException() :
RuntimeException("Empty priority queue") {}
};
// more code
#endif
Here is the RuntimeException header file:
#ifndef RUNTIMEEXCEPTION_H_
#define RUNTIMEEXCEPTION_H_
#include <string>
class RuntimeException {// generic run-time exception
private:
std::string errorMsg;
public:
RuntimeException(const std::string& err) { errorMsg = err; }
std::string getMessage() const { return errorMsg; }
};
inline std::ostream& operator<<(std::ostream& out, const RuntimeException& e)
{
out << e.getMessage();
return out;
}
#endif
Here is my main:
#include "PriorityQueueLinked.h"
#include "Comparator.h"
#include <iostream>
using namespace std;
int main() {
try {
PriorityQueueLinked<int,isLess> prique; // empty priority queue
prique.removeMin(); // throw EmptyPriorityQueueException
}
catch(...) {
cout << "error" << endl << endl;
}
getchar();
return 0;
}
My problem lies in not being able to configure a replacement for the "..." for catch. I've tried several things, one of them: "catch(PriorityQueueLinked < int,isLess > ::EmptyPriorityQueueException E)", but in this case it says that EmptyPriorityQueueException is not a member of PriorityQueueLinked. Any advice would be greatly appreciated.
Thanks
Try-catch supports inheritance with exception classes. catch (const RuntimeException & ex) will catch any subclass of RuntimeException, even if its private. This is the whole point of deriving exception classes.
By the way, never write using namespace std; is a header, you can never know who include it, and how. Also the standard library already has your genereal purpose exception class, and what a surprise! They also clall it runtime exception, exception it§s written like this: std::runtime_exception. You can find it in <stdexcept>.