-3

I am trying to save a local variable from a function by storing it's address. However, it appears that the compiler is automatically freeing the memory of that variable, even after I store it's address into a pointer variable.

I am in a situation (not exactly like the code below) where I must have a class's member variable store the address of a variable declared in a function.

#include <stdio.h>

static int* p;

void foo(){
    int a = 5;
    p = &a;
}

int main(){
    foo();

    //some delay

    printf("*p = %d\n",*p);
}

Ideally, *p should be 5, but it ends up being a number that isn't 5, and it's different much of the times I rerun the script. I believe that the memory allocated to a in foo is being freed automatically. How can I make sure *p is 5 despite any delay?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 4
    Why do you think you want to do this? –  Jul 03 '19 at 23:13
  • 1
    You cannot. Taking the address of a local and dereferencing it outside the scope where it's defined is UB. – 500 - Internal Server Error Jul 03 '19 at 23:14
  • See [this question](https://stackoverflow.com/questions/4570366/how-to-access-a-local-variable-from-a-different-function-using-pointers). – 1201ProgramAlarm Jul 03 '19 at 23:21
  • Originally, this question was tagged with both C ([tag:c]) and C++ ([tag:c++]). Then the C++ tag was removed, even though the question references 'class member variable' which is a non-concept in a C program. The answers, not unreasonably, use `new` and other bits of C++ (`unique_ptr`, `shared_ptr`, etc.). It is probably better tagged C++ than C, therefore — even if the sample code is better C code than C++. – Jonathan Leffler Jul 03 '19 at 23:33
  • what are `unique_ptr`/`shared_ptr `? – Condensation Jul 03 '19 at 23:38
  • @AlexB `unique_ptr` / `shared_ptr` are memory-managing pointers. If you are familiar with constructors with destructors, they automatically delete allocated data when the memory is no longer used. It is quite a big topic so I would try looking through tutorials to see if can be something that might help. – Michael Choi Jul 03 '19 at 23:43
  • 2
    [Prefer a highly recommended book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) to tutorials found by web searches. The Internet is littered with bad tutorials, some so bad that you'll become a worse programmer from reading them. Until you know the language well enough to tell good advice from bad, you'll be at the mercy of charlatans and blathering morons. If you are still interested in tutorials, seek out the acknowledged domain experts and use their tutorials or tutorials they recommend. Do not recommend tutorials unless you have a good one in mind. – user4581301 Jul 04 '19 at 00:20
  • 1
    Possible duplicate of [How to access a local variable from a different function using pointers?](https://stackoverflow.com/questions/4570366/how-to-access-a-local-variable-from-a-different-function-using-pointers) – JaMiT Jul 04 '19 at 01:26

4 Answers4

5

Solution 1 - dynamic memory allocation with new and delete

If you want a memory location to be accessible after a function exits, you should allocate it dynamically using new:

int* foo() {
    int* p = new int(5); // Get pointer to int with value of 5
    return p; 
}

Because that pointer was allocated with new, it'll stick around until you call delete on it:

int main() {
    int* myPtr = foo(); 

    // Do stuff with myPtr

    delete myPtr; // Free it, now that it's no longer needed.
}

Potential issues

When people talk about having to do manual memory management in C++, this is usually what they mean. Figuring out when to call delete on an object can be tricky, and it's easy to mess things up.

Solution 2 - variable a exists even after the function exits, and it's the same a every time the function is called

If we mark a as static, then it'll have the same memory address every time the function is called, and it won't be deallocated:

int* p;
void foo() {
    static int a = 5;

    p = a;
}

int main() {
    foo(); 

    // stuff...

    std::cout << *p << '\n'; // Prints 5, unless you modified *p
}

But why?

Oftentimes, when giving a good answer, it's helpful to understand why the person asking wants to do something. You don't provide any information about why you want to do this, so I don't know what (specifically) to propose.

Alecto Irene Perez
  • 10,321
  • 23
  • 46
  • And what *is* viable and more clever in your opinion? – Michael Chourdakis Jul 03 '19 at 23:40
  • @AlexB don't get too clever. You won't be able to debug it. Let the compiler get clever, then test it's cleverness with a profiler. If it is found wanting, get a little more clever with the worst parts. – user4581301 Jul 04 '19 at 00:12
1

If you want the variable inside foo to persist after the function call, then you must make a a static variable. C++ is a stack-based machine: that means the lifetime of a variable is restricted to it's scope. In your example a is restricted to the scope of foo. If you make your variable static, then it will extend the lifetime of your variable to the top-level scope, but will limit your access to a within your function.

I feel like what you are trying to do is very code smelly, but here is what you requested:

#include <stdio.h>

static int* p;

void foo(){
    static int a = 5; // a will only be initialized to 5 once (see magic statics)
    p = &a;
}

int main(){
    foo();

    //some delay

    printf("*p = %d\n", *p);
}

In this example you are guaranteed that a will be initialized upon your first call and will not be reused or deleted until the end of your program.

Michael Choi
  • 610
  • 5
  • 22
  • If I make `a` static within a function of a c++ class, will it be a global variable, a member variable, or will it only be accessible within that function? – Condensation Jul 03 '19 at 23:25
  • @AlexB You can treat it like a global variable that is only accessible within that function. – Michael Choi Jul 03 '19 at 23:26
  • And if I call the function again in the future but store `&a` into a different pointer, will that ruin my original pointer? – Condensation Jul 03 '19 at 23:27
  • @AlexB It will not. It simply means you have multiple points where you can change your data. – Michael Choi Jul 03 '19 at 23:40
  • Note that [`static` outside of a function](https://en.cppreference.com/w/cpp/language/storage_duration#Linkage) means something very different from [`static` inside a function](https://en.cppreference.com/w/cpp/language/storage_duration#Static_local_variables). And both are different from the meaning of [`static` inside a class](https://en.cppreference.com/w/cpp/language/static). – user4581301 Jul 04 '19 at 00:27
0

That is the point of using automatic storage variables, to vanish when they go out of scope. Pointing to them after they are destroyed is undefined behaviour. UB may return you a correct value, a wrong value, or crash your app, or whatever.

If you want to keep it, do not make it local. Use (and return) a unique_ptr/shared_ptr (although I do not see why you want to do that in your code anyway).

All the answers suggesting a static variable are bad. While it will work temporarily, it is bound to create lots of other problems if you make it a habit.

Michael Chourdakis
  • 10,345
  • 3
  • 42
  • 78
  • I tried having the function also return `a`, but leave the returned variable unused. Will this fix the issue? – Condensation Jul 03 '19 at 23:30
  • Smart pointers. They will auto destruct when not anymore needed. Never do new/delete again. – Michael Chourdakis Jul 03 '19 at 23:39
  • @MichaelChourdakis Of course binding a global pointer to a static variable is bad. Still, the question explicitly asks how to persist the pointer data after the function executes. Just because the premise of a question is 'bad' does not make accurate answers to that question bad. – Michael Choi Jul 04 '19 at 00:05
-1

Use a static variable, and it will solve your issue of it being 5. The memory on the other hand will not be saved due to the fact that it's a local variable.