Pointer to a local class variable?

Possible duplicate:
Can I access a local folder outside its area?

Does it make sense to make code like this (getIDs () returns a pointer):

class Worker{ private: int workerID; int departID; int supervisorID; public: Worker() { workerID=0; departID=0; supervisorID=0; name="anonymous"; workerAddress="none"; } void setIDs(int worker, int depart, int supervisor) { workerID=worker; departID=depart; supervisorID=supervisor; } int* getIDs() { int id[3]; id[0]=workerID; id[1]=departID; id[2]=supervisorID; return id; } }; 

And then use it like this:

 Worker obj; obj.setIDs(11,22,33); cout<<(*obj.getIDs())<<endl; cout<<++(*obj.getIDs())<<endl; cout<<++(++(*obj.getIDs()))<<endl; 

I am interested because the compiler shows:

Warning 1 warning C4172: returning local variable address or Temporary

+4
source share
6 answers

You return a pointer to a variable that is destroyed immediately after getIDs() returns. Then the pointer becomes dangling and almost useless, since the behavior with it is undefined.

Suppose you define your class as follows:

 class Worker{ private: int IDs[3]; public // ... int* getIDs() { return IDs; } }; 

This partially solves your problem as the pointer remains valid as long as the Worker object is in scope, but this is still bad practice. Example:

 int* ptr; while (true) { Worker obj; obj.setIDs(11,22,33); ptr = obj.getIDs(); cout << *ptr; // ok, obj is still alive. break; } // obj gets destroyed here cout << *ptr; // NOT ok, dereferencing a dangling pointer 

The best way to solve this is to implement your custom <<operator for your class. Something like that:

 class Worker { private: int workerID; int departID; int supervisorID; public: // ... friend ostream& operator<<(ostream& out, Worker w); }; ostream& operator<<(ostream& out, const Worker& w) { out << w.workerID << "\n" << w.departID << "\n" << w.supervisorID; return out; } 
+2
source

Your int id[3] is allocated on the stack and destroyed when int* getIDs() returned.

+3
source

Even if this worked, it would not be very good to do it in C ++ unless there is some deep reason why you need pointers to int. The original c-syle arrays are harder to handle than, for example, std::vector s, so use those that, for example,

 std::vector<int> getIDs(){ std::vector<int> id(3); id[0]=workerID; id[1]=departID; id[2]=supervisorID; return id; } 

If you are worried about overhead: this is probably fully optimized by modern compilers.

+2
source

A local (also automatic) variable is destroyed as soon as you leave the function where it is defined. That way, your pointer will point to this destroyed location, and, of course, a link to that location outside the function will be set and will cause undefined behavior.

+1
source

Edit: My apologies, I completely misunderstood the question. I should not respond to StackOverflow in front of my coffee.

If you want to return an array or pointer, then there are two routes.

One route: new

 int* n = new int[3]; n[0] = 0; // etc.. return n; 

Since n is now a cumulus, you can delete it later, if you do not delete it, it will eventually cause a memory leak.

Now, route two is a slightly simpler method that I find, but it is more risky. Here you pass the array and copy the values.

 void copyIDs(int arr[3] /* or int* arr */) { arr[0] = workerID; /* etc */ } 

Now your array is full and there is no heap allocation, so no problem.

Edit: returning a local variable as an address is bad. Why?

Given the function:

 int* foo() { int x = 5; return &x; // Returns the address (in memory) of x } // At this point, however, x is popped off the stack, so its address is undefined // (Garbage) // So here our code calling it int *x = foo(); // points to the garbage memory, might still contain the values we need // But what if I go ahead and do this? int bar[100]; // Pushed onto the stack bool flag = true; // Pushed onto the stack std::cout << *x << '\n'; // Is this guaranteed to be the value we expect? 

All in all, this is too risky. Do not do this.

+1
source

The main problem is that when you enter a function call, you get a new frame in your stack (where all your local variables will be stored). Anything that is not dynamically allocated (using new / malloc) in your function will exist in this stack frame, and it will be destroyed when your function returns.

Your function returns a pointer to the beginning of your 3-element array, which you declared in this stack frame, which will disappear. So this is undefined behavior .

While you can get happy / unsuccessful and still have your data where the pointer indicates when you use it, you can also have the opposite with this code. Since space is discarded when the stack frame is destroyed, it can be reused, so another part of your code can probably use a memory cell that stores your three elements in this array, which means that they will have completely different values โ€‹โ€‹when you dereferenced this pointer.

If you're lucky, your program will simply disappear / crash, so you knew you made a mistake.

Redesign your function to return a structure of three integers, a vector, or at least (and I do not recommend it), dynamically highlight the contents of the array with a new one so that it remains after the function is called (but you better remove it later, or the gremlins will come and deliver you ...).

+1
source

Source: https://habr.com/ru/post/1384108/


All Articles