I was creating a custom exception in c++ for the program I'm creating, it's an interpreter and one exception I need to create is EOL Error
among others. I made my header file and my .cpp
. I did the implementation and overloading of the necessary methods and everything was fine until the moment of throwing the exception and catching it. I'm leaving part of the code.
Exceptions.h
#pragma once
#include <iostream>
#include <string>
namespace Exceptions
{
class EOLError : public std::exception
{
private:
int linea;
std::string message;
public:
EOLError();
EOLError(int num_linea, string linea);
const char * what() const throw();
};
}
Exceptions.cpp
#include "Exceptions.h"
#include <iostream>
#include <string>
using namespace Exceptions;
using namespace std;
EOLError::EOLError(){}
EOLError::EOLError(int linea, string msg){
this->linea = linea;
message = msg;
}
const char* EOLError::what() const throw(){
string msg = string(to_string(linea)) + " | " + message;
return msg.c_str();
}
main.cpp
#include <iostream>
#include <fstream>
#include <string>
#include "Exceptions.cpp"
int main(){
try
{
int num_linea = 1;
string linea = "var = \"hola\"";
if(linea[linea.size() - 1] != ';') throw EOLError(num_linea, linea);
}
catch(const exception& e)
{
cout << e.what() << endl;
}
return 0;
}
When showing the exception I get strange things in the console, practically as if it were garbage, but if I add a cout << msg;
before the return it shows me the message.
What it should show would be this:
1 | var = "hola"
What should I do so that the message is displayed correctly? Can't I just create variables in that method?
Your error is very simple:
There you are creating an automatic variable
msg
. And you use a data from that variable as the data that you return... with the characteristic that the data in question is a pointer managed by the variable itselfmsg
:string
it is responsible for managing that memory... and freeing it when necessary.Automatic variables have a limited lifetime associated with their scope. In your case, the variable
msg
ceases to exist on arrival atreturn
... and then performs all the indicated operations in its destructor, including freeing any internally used memory ...And we arrive at the outcome: what you receive outside is a pointer to a memory area managed by a variable that no longer exists... and that no longer contains what you expect. And any attempt to access that position is undefined behavior.
The simplest solution is to perform that operation in your own constructor , so you won't need to create that variable on the fly :
And with that you no longer need the member-variable
linea
in yourEOLError
.