1

I'm trying to return a string from a function like this:

virtual const char* what() const throw()
{   
    std::string str = "Name Error: name ";
    str+= n_name;
    str += " is not defined";
    char ret[256]="";
    const char* temp = str.c_str();
    strcpy(ret, temp);
    return ret;
}

But when I try to print it in another place:

const char* str= exc.what();
std::cout << str;

The output is garbage.

I thought the problem was the char[] and it should be char*, but when I changed it to

char* ret="";

the program crashed at

strcpy(ret, temp);

Can someone please help me? P.S. the function has to return a const char*

Garf365
  • 3,619
  • 5
  • 29
  • 41
  • 1
    You return a pointer to invalid memory. You need to allocate some memory to which you pointer will point. See 'malloc' or 'new[]'. – ZunTzu May 31 '16 at 15:13

3 Answers3

0

By the moment what() returns and the return value is stored into str the array ret will have been destroyed because of it's scope and this the pointer returned from what() is a dangling pointer which causes undefined bevahiour upon derefencing. You should either new the array (and delete it after using it) or just return a std::string.

Hatted Rooster
  • 35,759
  • 6
  • 62
  • 122
0

Main problem comes from returning pointer to a local variable. If you use -Wall compiler option (which I encourage you to use in every compilation you done), you will get:

warning: address of local variable 'ret' returned [-Wreturn-local-addr]

Indeed, char ret[256]=""; is local to function. At the end of function, local variables don't exist anymore. So, when std::cout << str; is executed, pointed memory doesn't exist anymore.

When you use char* ret="";, you don't allocate memory. You just have a pointer which point to a read-only static memory containing "". And always with -Wall option, you will get an warning which says you are doing something wrong:

warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]

You have to allocate memory:

char * ret = new char[str.size()+1];

But take care, each new have to have somewhere a delete => every manually allocated memory should be deallocated manually

Garf365
  • 3,619
  • 5
  • 29
  • 41
  • Are you sure char ret[256]="" allocates memory? How is it different from char* ret="" which points to read-only static memory? – ZunTzu May 31 '16 at 15:26
  • `char ret[256]=""` automatically allocate memory on stack for 256 `char` and initialize it to `""`. Deallocation is automatically done at the end of function – Garf365 May 31 '16 at 15:31
  • Thank you so much! It works now! – alonpeer12345 May 31 '16 at 15:35
0

It looks like you're trying to implement an exception. Why don't you just inherit from std::runtime_error which already provides the machinery to make this work? You just need to pass your desired message to its constructor.

See http://en.cppreference.com/w/cpp/error/runtime_error

Alan Stokes
  • 18,815
  • 3
  • 45
  • 64