This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 8 years ago.
I guess this is a very basic question, but even after looking around on the internet for a while I can't seem to find a proper answer to this question.
I will refer to this tutorial on stack/heap:http://gribblelab.org/CBootcamp/7_Memory_Stack_vs_Heap.html
Let's say I write the following code:
void testVoid() {
int testVariable = 5;
}
If I'm not wrong, this function should create a variable located on the stack. As the functions exits, the allocated memory on the stack is deleted - so my variable should also have been deleted by then.
I have learned that pointers in c++ point to the memory location of a variable.
So if the variable pointed to by a pointer is located on the stack, and the stack then is cleared, I would expect not to be able to access original value through the pointer anymore, since the memory location pointed to is is cleared. However, I tested this:
int* pointer;
void testVoid() {
int num = 3;
pointer = # // Here I get the memory location of my num-variable
cout << pointer << " : " << *pointer << endl; // I would get the same result if i printed &num
}
int main(int args, char** argv) {
pointer = new int;
testVoid();
cout << pointer << " : " << *pointer << endl; // I can still access the memory of my num-variable
while (true) {}
return 0;
}
After exiting the testVoid()-function, where the variable is created, I can still get the value of the variable using my pointer. So obviously I have misunderstood something regarding how pointers work in c++. Printing &pointer and &num gives me the same memory location, even after testVoid() has finished. What is the reason for this? If the memory pointed to by the pointer were moved to the heap, shouldn't cout<<&num and cout<
And here's the output:
0024F904 : 3
0024F904 : 3
Just because the value goes out of scope does not mean the memory for the value has been overwritten. You just can't rely on it being stable at that point.
Related
This question already has answers here:
Why use new and delete at all?
(8 answers)
Use of new and delete in C++
(5 answers)
C++ is it necessary to delete dynamically allocated objects at the end of the main scope?
(7 answers)
Closed 3 years ago.
I am currently learning about dynamically allocated memory and have written a short program for practise.
Here is the main function:
int main() {
// Local variables are stored in the stack.
// The heap is a pool of unused memory that can be used when the program dynamically allocates memory.
// The `new` operator allocates memory within the heap and returns the address of that variable:
int *p = new int;
*p = 5;
cout << "A variable has just been allocated in the heap" << endl;
cout << "Its memory address is: " << p << endl;
cout << "Its value is: " << *p << endl;
// For local variables on the stack, memory management is performed automatically.
// But on the heap, it must be done manually.
// Memory must be freed when no longer needed:
delete p; // This frees up the memory pointed to by p.
// The `delete` keyword frees up the memory allocated for the variable, but does not delete the pointer p, because p is stored on the stack.
// p is now a dangling pointer, it points to a non-existent memory location.
// To test that it worked:
cout << "The memory previously pointed to has now been deleted." << endl;
cout << "Its memory address is: " << p << endl;
cout << "Its value is: " << *p << endl;
}
So far it makes sense, except for line delete p. At that point, the memory is supposed to be 'freed up'. I read the following page for information:
Delete in c++ program is not freeing up memory
The answer said:
Calling delete whatever marks that memory as deallocated and free for future use.
However, when I run the program, the two sets of cout statements output the same thing, which to me suggests that the memory has not been freed up, as p still points to the same location, which has the same value.
After some tinkering, I found that I can reallocate p whether or not I ran delete p and I could change the memory address and its value in either case.
So what exactly does delete p do, I don't notice it making any difference to the program?
This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 7 years ago.
Here is a simple of example of a question I have:
I create a pointer of integer (value 5), I print the pointer (hence the address) of the memory case it points to, as well as its content (5).
Then I delete that pointer, which is supposed to delete the content in the memory case that has the address of the pointer.
But then when I print a and its content, as expected the address still exists. Nevertheless the content remains the same (5) as if a was not deleted...
could you explain me? :-)
#include <iostream>
int main()
{
int * a = new int(5);
std::cout<< a << std::endl;
std::cout<< "--------" << std::endl;
delete a;
std::cout<< a << std::endl;
std::cout<< *a << std::endl;
// end of my main
return 0;
}
result:
0x7fff28403a90
--------
0x7fff28403a90
5
It may or may not print the same value after delete operation. So simply what you are observing is an undefined behavior.
This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 7 years ago.
So I'm learning C++ (coming from a Java background). I thought I understood how memory works on a high level (stack vs heap and pointers). To experiment, I wrote the following two toy functions:
int* pntrToHeap(int val) {
return new int(val);
}
and
int* pntrToStack(int val) {
return &val;
}
At first I thought pntrToStack just wouldn't work, because the local variable val is on the stack which is "deleted" after the function exits. But after the following code worked without errors (with 1 warning, however), I reconsidered:
int main()
{
int val1 = *pntrToHeap(3);
int val2 = *pntrToStack(4);
cout << val1 << endl;
cout << val2 << endl;
return 0;
}
Both 3 and 4 printed to the screen. It seems as though the stack isn't actually deleted, but the CPU just loses the ability to access local variables on it -- is this correct? If so, in a case like this, which function should we prefer?
Lastly, since val1 is a local variable of main, is pntToHeap creating a memory leak since I can't delete the value it created on the heap?
I know these concepts have been asked about before, but I couldn't quite find the answers. Thanks!
Definitely the first one! If you want something to live after the stack frame expires you should heap allocate it.
And yes, the value pointed to by the pointer returned from pntrToStack will be overwritten the next time you allocate a new stack frame ie. call a function. When you exit out of a scope the memory is not erased. It is merely marked as being free to allocate.
This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 8 years ago.
Please consider this simple example:
#include <iostream>
const int CALLS_N = 3;
int * hackPointer;
void test()
{
static int callCounter = 0;
int local = callCounter++;
hackPointer = &local;
}
int main()
{
for(int i = 0; i < CALLS_N; i++)
{
test();
std::cout << *hackPointer << "(" << hackPointer << ")";
std::cout << *hackPointer << "(" << hackPointer << ")";
std::cout << std::endl;
}
}
The output (VS2010, MinGW without optimization) has the same structure:
0(X) Y(X)
1(X) Y(X)
2(X) Y(X)
...
[CALLS_N](X) Y(X)
where X - some address in memory, Y - some rubbish number.
What is done here is the case of undefined behaviour. However I want to understand why there is such behaviour in current conditions (and it is rather stable for two compilers).
It seems that after test() call first read of hackPointer leads to valid memory, but second successive instant read of it leads to rubbish. Also on any call address of local is the same. I always thought that memory for stack variable is allocated on every function call and is released after return but I can't explain output of the program from this point of view.
"Releasing" automatic storage doesn't make the memory go away, or change the pattern of bits stored there. It just makes it available for reuse, and causes undefined behaviour if you try to access the object that used to be there.
Immediately after returning from the function, the memory occupied by the local probably hasn't been overwritten, so reading it will probably give the value that was assigned within the function.
After calling another function (in this case, operator<<()), the memory is likely to have been reused for a variable within that function, so probably has a different value.
You are quite right that this is undefined behaviour.
That aside, what's happening is that std::cout << *hackPointer involves a function call: operator<<() gets called after the value of *hackPointer has been read. In all likelihood, operator<<() uses its own local variables that end up on the stack where local was, wiping out the latter.
This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 8 years ago.
Given the following code snippet:
#include <iostream>
using namespace std;
int *pPointer;
int func()
{
int num;
num = 25;
pPointer = #
}
int main()
{
func();
cout << *pPointer << endl;
cout << *pPointer << endl;
return 0;
}
Can anyone tell me if I duplicate the following line:
cout << *pPointer << endl;
cout << *pPointer << endl;
Why I receive 25 (as expected) but then the next value is 0 (NULL)?
Wouldn't the value of int=25 still remain on the stack? What is it about cout that changes the value of pPointer? Am I missing something about my understanding about scope and the stack? (I'm a Java guy, so this was surprising).
This is because pPointer is pointing to a local variable in func(). This area of memory is only valid inside of the func() method. After func() exits, the memory that pPointer points to is free to be re-used, and appears to be used by cout.
If you want to persist this memory, you should either save it by value, or allocate the memory dynamically pPointer = new int(num)
num does not exist once the function func() terminates.
You take its address when it exists, then attempt to print the value at an address that is no longer valid.
Anything can happen.
As it is undefined behavior, there is no num outside of func scope.
cout << *pPointer << endl;
here *pPointer is pointing to a local variable of some other function which already returned so the address to which it is pointing is out of scope so the behaviour is undefined. it may print the right value assigned to num or may not.
Why I receive 25 (as expected) but then the next value is 0 (NULL)?
What you mention as expected is actually not expected!
num becomes out-of-scope as soon as func() returns. Although pPointer is valid (as it is global), *pPointer is not, because it is pointing to a out-of-scope memory.