-1

Hello i am building a project and today after 500 lines of code i am going to shoot my self. Today i started a new class and some very strange things are happening:

class Target {
public:
Target(const int port);
virtual ~Target();

private:
    const char*  initialize_port(const int port) const;
    const char *const port;
};

and cpp file:

Target::Target(const int port)
:
port(initialize_port(port))

{
     cout<<this->port<<endl; //this cout 80
     string test3="Target2";//when i replace with char * test3="Target2" then both couts in the  constructor are working ok.
     cout<<this->port<<endl; //this cout Target2!!!!!!
}


const char* Target::initialize_port(const int port) const {

    string port_str = std::to_string(port);
    const char* port_char=port_str.c_str();
    return port_char; // OR/and when i replace with something like return "80" then both couts in the  constructor are working ok.

}


Target::~Target() {
}

Like you can see in the cpp file, while the default constructor is being called it couts the "this->port", then i create a string, and then i print it again. How is it even possible to get a different response??

From netbeans:

80

Target2

RUN FINISHED; exit value 0; real time: 20ms; user: 0ms; system: 0ms


PS:When in the function initialize_port(const int port) i am giving a standard return, for example return "80"; everything is ok. When in the constructor i am replacing the string with char *, again everything is ok.

PS2:I know that i have some problems with my RAM. If someone will compile and there is no problem with the outputs (cout) please let me know.

Thanks in advance.

  • 4
    If you want to store a string, use `string`. You have a dangling pointer and undefined behaviour. – Alan Stokes Aug 10 '15 at 22:10
  • Nothing relevant for diagnosis of whatever concrete question was posted here, sorry! – πάντα ῥεῖ Aug 10 '15 at 22:11
  • I sincerely hope that "and today after 500 lines of code i am going to shoot my self" is just an incorrect translation?? – villintehaspam Aug 10 '15 at 22:12
  • @πάντα ῥεῖ funny nickname. But it doesn't "Always flow". Your nickname isn't an ancient motto. Propably you want to say " Τα πάντα ρεί " which means "Everything flows". Slight differences change the meaning. and sometimes the answers too ;-) – Dimopoulos Elias Aug 11 '15 at 22:57
  • @DimopoulosElias I suspect you as a native speaker are better able than me to judge _the motto_. Anyway you got well I'm sometimes unreliable in my behavior ;-) ... – πάντα ῥεῖ Aug 11 '15 at 23:02
  • Anyway, your question actually is a duplicate of http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope and is essentially answered there. – πάντα ῥεῖ Aug 11 '15 at 23:24

2 Answers2

3

The problem comes from:

{
   string port_str = std::to_string(port);
   const char* port_char=port_str.c_str();
   return port_char; 
}

When the return happens, port_str is destroyed because it is a locale variable to that code block. Then port_char is a dangling pointer (a pointer that used to point to an object that has now been destroyed).

Using that pointer causes undefined behaviour and that explains your weird effects when you use the pointer.

To fix this, stop using raw pointers. The simplest fix is to use std::string instead.

M.M
  • 138,810
  • 21
  • 208
  • 365
0

The problem is that the return value of port_str.c_string() is only valid for the lifetime of port_str. Since that is allocated on the stack in initialize_port it becomes invalid once that function returns.

In your constructor, when you initialize the test3 string it ends up (mostly by chance) occupying the same memory as port_str did.

If you need to use a const char * you will need to allocate new memory for the string inside initialize_port (and deallocate it in your constructor!). Alternatively just stick with using std:string objects.

Hargo
  • 1,256
  • 1
  • 16
  • 24