The accepted answer is a little misleading.
When you use malloc(), the memory
returned by that can be accessed
anywhere in your code, assuming that
you can see the variable which has the
pointer returned by malloc().
This is equally true of any memory allocated in C or C++, whether heap, stack or static. Just put & in front of a local variable, and you now have the key that allows any other part of the program to get at the storage for that variable, and use it just as effectively as if they could see the variable name itself.
Local variable names are only visible inside the scope they are declared in, but their storage is accessible from anywhere, in any thread, assuming the address has been taken and passed around.
It dangerous, and yet frequently necessary, to take the address of local variables in C/C++, and so it is unfortunately impossible to use those languages effectively without understanding this.
UPDATE
@kevinf says:
Using the address of a local within the scope of the local is fine, but your suggestion is NOT memory safe
It's important to distinguish between scope and lifetime. Scope refers to identifiers (e.g. variable names), and it is the set of locations in your code where the identifier can be mentioned. It's a compile-time concept.
This is a separate concept from memory safety, or lifetime of an object in a storage location. This is a runtime concept. For example:
void g(int *p)
{
(*p)++;
}
void f()
{
int n = 1;
g(&n);
}
Here, the identifier n
is only in scope within f
. It names a storage location that exists while f
is running. We get the address &n
of that storage location and pass it to g
. Note that g
cannot use the name n
directly. n
is not in scope here! Yet the storage location is perfectly usable in this example because f
is still unfinished (waiting for g
to complete).
Most real C and C++ programs do this a lot, and it is allowed by the standard. It is neither generally safe nor generally unsafe. It is sometimes safe and sometimes not. This is the core challenge with C and C++. Undefined behaviour is not always detectable from local examination of a function; you have to know how it is being used in a wider context.
More recent changes to the language (in g++ use the -std=c++14
option to compile this) introduce other ways of exploring this grey area:
auto f()
{
int n = 1;
auto g = [&]
{
++n;
cout << "Incremented to " << n << endl;
};
g();
return g;
}
void h()
{
auto g = f();
cout << "Returned into h" << endl;
g();
}
Inside f
, n
is in scope. And g
holds an instance of a lambda, the body of which is also part of the scope of n
. And the call to g
inside f
is perfectly fine. But in f
when we store the lambda in another variable called g
, the subsequent call to it is not allowed! We have, without ever using &n
, implicitly captured a storage location that is no longer available to us, because its lifetime was limited to the duration of our call to f
.
By the way, when I say not allowed, it will compile. But on my system it prints:
Incremented to 2
Returned into h
Incremented to 167772162
Which clearly demonstrates undefined behaviour.