-3

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?

cercio
  • 41
  • 5
  • `_BADALLOC` identifier is reserved to the language implementation. By defining it, your program will have undefined behaviour. You should use another macro as a header guard. – eerorika Aug 31 '20 at 17:51
  • Names that begin with an underscore followed by a capital letter (`_BADALLOC`) and names that contain two consecutive underscores are reserved for use by the implementation. Don’t use them in your code. – Pete Becker Aug 31 '20 at 17:59
  • Thanks for your suggestions, i changed the identifier. The problem still remains unfortunately – cercio Aug 31 '20 at 18:01

1 Answers1

2

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
john
  • 85,011
  • 4
  • 57
  • 81
  • i already tested it earlier and i checked again now, i can create a badalloc object and use its what() function properly, the program runs just fine. It was not me to dislike your comment, i appreciate any help – cercio Aug 31 '20 at 17:46
  • @cercio Surely you can see that you are copying to an uninitialised pointer? Until you fix that error the behaviour of your code will be unpredictable. – john Aug 31 '20 at 17:47
  • so what would be a solution? – cercio Aug 31 '20 at 17:49
  • There are many solutions. The simple one is to use a `std::string` instead of a pointer. – john Aug 31 '20 at 17:50
  • Quite simple solution is `char Message[some_magic_number];` – Slava Aug 31 '20 at 17:56
  • @cercio I've added some suggested code to the answer. Slava's suggestion would also work. – john Aug 31 '20 at 17:58
  • As you suggested, i modified my class: class badalloc{ private: string Message; double Number; public: explicit badalloc(string S="Error",const int & N=0): Message(S), Number(N); string what () const {return Message;} }; Nothing has changed( i tried with and without the inizializer list) – cercio Aug 31 '20 at 17:58
  • 2
    @cercio As you can see here http://cpp.sh/3xnq7 my code works fine. You must have issues elsewhere in your program. – john Aug 31 '20 at 18:04
  • @cercio this is one of the many reason that "Fix the Bug" type questions are required to contain a [mre]. – user4581301 Aug 31 '20 at 18:27
  • @john - It's not really a good idea to use `std::string` as a member of a class that will be thrown as an exception. The construction of `std::string` can throw, which means the act of attempting to throw the user-defined exception (`badalloc` in this case) can throw a completely different (like `std::bad_alloc`). There is a reason that standard exceptions aren't specified as containing a member that can throw. – Peter Aug 31 '20 at 19:11
  • For anyone wondering, i solved it. I managed to make it work while keeping my char * Message. Used an inizialiter list instead of my original inline code. – cercio Aug 31 '20 at 19:27
  • @cercio -- *I managed to make it work* -- This sounds like you don't know why it works. Until you know the reason for this to work, the problem really hasn't been fixed. If you're just trying code until something *seems* to work, then that's worse because you could get the false sense that you actually fixed the problem. When working with C++, **every** coding bug that has a fix **must** be explainable, fully and completely. – PaulMcKenzie Aug 31 '20 at 19:50
  • @PaulMcKenzie I have an idea on why it works, i just can’t be 100% sure about it, since im by no means an expert. I think that the reason is that by using an inizialiter list the char pointer gets allocated and initialized at the same time when the object is created, as opposed to using the inline code in which the pointer gets allocated initially with an unkown value and later it gets initialized. You seem to be more experienced, perhaps you can share an explaination alongside your valuable advise? – cercio Aug 31 '20 at 21:44
  • *later it gets initialized* -- Actually, initialization occurs when the variable is created, not afterwards. If a variable already exists, and you happen to change the variable, that is assignment, not initialization. So possibly you are correct in that the brace-initialization actually initializes, so you are in a valid state immediately. Without seeing what your fix was, that's the best guess. – PaulMcKenzie Aug 31 '20 at 21:53