When the memory is allocated to a function.
For example:
int doubleMe(int smthng){
int dbl = 2*smthng; //line 2
return dbl;
}
void main(){
int var;
printf("The double of var is: %d",doubleMe(var)); //line 8
}
When is memory allocated to variable dbl?
when is defined (line 2) (compile time)
or when function is called (line 8)(run time)
I believe it is allocated when function is called(run-time) in stack. And freed when function exits, is it? Would be great if someone could please explain it better.
This question looks similar but not quite!
The compiler generates object code of a function when it is defined. The generated code contains instructions to allocate memory in the stack for function local variables or it can use registers to accomodate them.
Where a function is called the compiler generates object code of the function call and corresponding instructions to push arguments on the stack. At this point the compiler may not to know how the function is defined and whether it is defined because its definition can be in some other module or library.
Take into account that the compiler may inline functions even if you yourself do not use function specifier inline. In this case it will place the function definition in the point where the function is called.
Memory is allocated to variable dbl(or var) at compile time in the stack memory
Not correct, it is allocated in run-time, just as all other stack variables. That's the whole point of using a stack. It is allocated when your function is called, in run-time.
I believe it is allocated when function is called. And freed when function exits, is it?
Yes.
Regarding your statement: Memory is allocated to variable dbl(or var) at compile time
No, The instructions to allocate memory are created at compile time.
Memory is not allocated until that function is executed.
Memory created inside a function is an example of local scope memory. if it is created on the stack, it will be released upon leaving the scope in which it was created. If it was created on the heap (i.e. created using [m/c/re]alloc() functions) it will not be released (or more accurately, made available as described here) until free() is called, or at program exit.
Later, you state:
I believe it is allocated when function is called. And freed when function exits.
This statement is true, but this all happens at run-time only. Not at compile-time.
For global scope memory, stack memory is created when the program is executed, and is not released until the program ends. Again, for heap memory , it will be released upon calling free(), or at program exit.
It's not allocated during compilation at all, but at runtime.
When the function is called during execution, either space will be reserved for it in memory (in approximately 100% of current C++ implementations, "on the stack") or it will reside in a register.
If it's not in a register, the space is freed when the function returns.
The compiler produces code that will perform the runtime allocation, if there is any.
Related
Can anyone tell me how many times variable integer1 allocated and deallocated?
how about class_object? Is it true that both of them allocate and deallocate three times?
for(int i = 0; i < 3; i++){
int integer1;
Class1 class_object(some_parameter);
}
For local variables allocation and deallocation is something compiler specific. Allocation/deallocation for local variables means reserving space on the stack.
Most compilers though will move the allocation and deallocation of the variables out of the loop and reuse the same space for the variable every time.
So there would be one allocation, meaning changing the stack pointer, before the loop and one deallocation, meaning restoring the stack pointer, after the loop. Many compilers will compute the maximum space needed for the function and allocate it all only once on function entry. Stack space can also be reused when the compiler sees that the life time of a variable has ended or that it simply can't be accessed anymore by later code. So talking about allocation and dealocation is rather pointless here.
Aren't you more interested in the number of constrcutions and deconstructions hapening? In that case yes, the constructor for Class1 is called 3 times and the destructor too. But again the compiler can optimize that as long as the result behaves "as if" the constructor/destructor were called.
PS: if the address of something is never taken (or can be optimized away) then the compiler might not even reserve stack space and just keep the variable in a register for the whole lifetime.
For automatic (local stack) variables the compiler reserves some space on the stack.
In this case (if we ignore optimizations) the compiler will reserve space for integer1 and class_object that most probably will be reused in each loop iteration.
For basic data types nothing is done beyond this but for classes the compiler will call the constructor when entering the scope of the variable and call the destructor when the variable goes out of scope.
Most probable both variable get the same address on each loop iteration (but this does not have to be true from the standards point of view).
The term allocation usually refers to requesting some heap memory or other resource from the operating system. Regarding to this definition there is nothing allocated.
But assigning some stack space (or a register) to a automatic variables may also be called allocation most compiler will allocate memory once (by setting the stack frame to a value big enough on entering the routine.
Summary:
At the end it is totally up to the compiler. You are just guaranteed to get a valid object in its scope
Is it possible to create memory leak in C++ without heap allocation, through very bad design ?
One example I had in mind, please correct me if it does not do what I think it does:
#include <iostream>
#include <string>
void WhatIsYourName()
{
std::string name;
std::cout << "What is your name? ";
getline (std::cin, name);
std::cout << "Hello, " << name << "!\n";
WhatIsYourName();
}
int main()
{
WhatIsYourName();
}
To me it looks like WhatIsYourName() is initializing a new std::string name on every call, but the function never really goes out of scope so the memory is never released.
Is that right ? Or is the compiler smart enough to see that the variable will not be used in the future, so it deletes it without the function going out of scope ?
What kind of other bad design would create a memory leak using only stack allocation ?
You have a recursive call that doesn't stop (there's no exit condition), so a new stack page is created for every function invocation, until of course the program crashes due to stack overflow. The compiler cannot optimize that away.
Regarding your last question, whether is possible to create a memory leak without heap allocation (and without this kind of infinite recursion), I believe it is not, the local variables are automatically released, that's why this type of storage duration is called automatic storage duration.
No it is not possible to create a memory leak with objects that have automatic storage duration (some people call this stack). When you have a variable with automatic storage duration it is cleaned up by the program automatically. Once the scope ends that it was declared in it gets destroyed and any resources it had are freed (as long as it was designed properly). In your example even though you never exit the scope due to infinite recursion it is not a memory leak. If the infinite recursion was removed and instead it ended at some condition then all the variables you declared would be cleaned up.
To get a memory leak you need to create a object with dynamic storage duration (what some people call heap) and never clean it up. When you have a object with dynamic storage duration the compiler does not clean it up for you. You need to make sure you clean it up yourself. It is this forgetting or leaving out of the clean up code that causes a memory leak.
The question is more interesting than you probably thought. There is no memory leak by definition, since memory leak can only be happening if a) a pointer to the allocated memory is lost (not the case here) or b) the pointer is never freed until program exits normally. The second is not the case either, since this program will never exit normally.
However, there is an interesting question of what actually happens to the string variable. Since the recursive call happens in the end of the function, from the glance it might seem that the code will be a candidate for tail-call optimization. However, if you check the assembly, it does not happen, because compiler needs to call string destructor after the return from the tail-call. I personally see this is a flaw in the optimization, since potentially compiler should be able to see that string variable is not used after the call and destruct it in advance.
I think you have misunderstood what a memory leak is in C and C++ worlds.
Given your condition "without heap allocation", it's not possible to leak memory.
A memory leak is typically associated with dynamic memory allocation(s) and then losing the ability to deallocate it.
For example:
// Memory leak
int x;
int *q = new int;
q = &x; // memory leak because the "allocated" q is lost.
With RAII and not using new + delete for memory management, it's easily avoidable in C++.
If the compiler has a bug, you could have a stack memory leak. For some obscure reason it "forgets" to call the destructor of a local variable. Check GCC bug 66139.
People always talk about how objects created without the new keyword are destroyed when they go out of scope, but when I think about this, it seems like that's wrong. Perhaps the destructor is called when the variable goes out of scope, but how do we know that it is no longer taking up space in the stack? For example, consider the following:
void DoSomething()
{
{
My_Object obj;
obj.DoSomethingElse();
}
AnotherFuncCall();
}
Is it guaranteed that obj will not be saved on the stack when AnotherFuncCall is executed? Because people are always saying it, there must be some truth to what they say, so I assume that the destructor must be called when obj goes out of scope, before AnotherFuncCall. Is that a fair assumption?
You are confusing two different concepts.
Yes, your object's destructor will be called when it leaves its enclosing scope. This is guaranteed by the standard.
No, there is no guarantee that an implementation of the language uses a stack to implement automatic storage (i.e., what you refer to as "stack allocated objects".)
Since most compilers use a fixed size stack I'm not even sure what your question is. It is typically implemented as a fixed size memory region where a pointer move is all that is required to "clean up" the stack as that memory will be used again soon enough.
So, since the memory region used to implement a stack is fixed in size there is no need to set the memory your object took to 0 or something else. It can live there until it is needed again, no harm done.
I believe it depends where in the stack the object was created. If it was on the bottom (assuming stack grows down) then I think the second function may overwrite the destroyed objects space. If the object was inside the stack, then probably that space is wasted, since all further objects would have to be shifted.
Your stack is not dynamically allocated and deallocated, it's just there. Your objects constructors and destructors will get called but you don't get the memory back.
Because people are always saying it, there must be some truth to what they say, so I assume that the destructor must be called when obj goes out of scope, before AnotherFuncCall. Is that a fair assumption?
This is correct. Note that this final question says nothing about a stack". Whether an implementation uses a stack, or something else, is up to the implementation.
Objects created "on the stack" in local scope have what is called automatic storage duration. The Standard says:
C++03 3.7.2 Automatic storage duration
1/ Local objects explicitly declared auto or register or not
explicitly declared static or extern have automatic storage duration.
The storage for these objects lasts until the block in which they are
created exits.
2/ [Note: these objects are initialized and destroyed as described in
6.7. ]
On the destruction of these objects:
6.7 Declaration statement
2/ Variables with automatic storage duration (3.7.2) are initialized
each time their declaration-statement is executed. Variables with
automatic storage duration declared in the block are destroyed on exit
from the block (6.6).
Hence, according to the Standard, when object with local scope fall out of scope, the destructor is called and the storage is released.
Weather or not that storage is on a stack the Standard doesn't say. It just says the storage is released, wherever it might be.
Some architectures don't have stacks in the same sense a PC has. C++ is meant to work on any kind of programmable device. That's why it never mentions anything about stacks, heaps, etc.
On a typical PC-type platform running Windows and user-mode code, these automatic variables are stored on a stack. These stacks are fixed-size, and are created when the thread starts. As they become instantiated, they take up more of the space on the stack, and the stack pointer moves. If you allocate enough of these variables, you will overflow the stack and your program will die an ugly death.
Try running this on a Windows PC and see what happens for an example:
int main()
{
int boom[10000000];
for( int* it = &boom[0]; it != &boom[sizeof(boom)/sizeof(boom[0])]; ++it )
*it = 42;
}
What people say is indeed true. The object still remains in the memory location. However, the way stack works means that the object does not take any memory space from stack.
What usually happens when memory is allocated on the stack is that the stack pointer is decremented by sizeof(type) and when the variable goes out of scope and the object is freed, the stack pointer is incremented, thus shrinking the effective size of data allocated on the stack. Indeed, the data still resides in it's original address, it is not destroyed or deleted at all.
And just to clarify, the C++ standard says absolutely nothing about this! The C++ standard is completely unaware of anything called stack or heap in sense of memory allocation because they are platform specific implementation details.
Your local variables on stack do not take extra memory. The system provides some memory from each thread's stack, and the variables on the stack just use part of it. After running out of the scope, the compiler can reuse the same part of the stack for other variables (used later in the same function).
how do we know that it is no longer taking up space in the stack?
We don't. There are way to see whether they do or don't, but those are architecture and ABI specific. Generally, functions do pop whatever they pushed to the stack when they return control to the caller. What C/C++ guarantees is that it will call a destructor of high-level objects when they leave the scope (though some older C++ like MSVC 6 had terrible bugs at a time when they did not).
Is it guaranteed that obj will not be saved on the stack when AnotherFuncCall is executed?
No. It is up to the compiler to decide when and how to push and pop stack frames as long as that way complies with ABI requirements.
The question "Is something taking up space in the stack" is a bit of a loaded question, because in reality, there is no such thing as free space (at a hardware level.) A lot of people (myself included, at one point) thought that space on a computer is freed by actually clearing it, i.e. changing the data to zeroes. However, this is actually not the case, as doing so would be a lot of extra work. It takes less time to do nothing to memory than it does to clear it. So if you don't need to clear it, don't! This is true for the stack as well as files you delete from your computer. (Ever noticed that "emptying the recycle bin" takes less time than copying those same files to another folder? That's why - they're not actually deleted, the computer just forgets where they're stored.)
Generally speaking, most hardware stacks are implemented with a stack pointer, which tells the CPU where the next empty slot in the stack is. (Or the most recent item pushed on the stack, again, this depends on the CPU architecture.)
When you enter a function, the assembly code subtracts from the stack pointer to create enough room for your local variables, etc. Once the function ends, and you exit scope, the stack pointer is increased by the same amount it was originally decreased, before returning. This increasing of the stack pointer is what is meant by "the local variables on the stack have been freed." It's less that they've been freed and more like "the CPU is now willing to overwrite them with whatever it wants to without a second thought."
Now you may be asking, if our local variables from a previous scope still exist, why can't we use them? Reason being, there's no guarantee they'll still be there from the time you exit scope and the time you try to read them again.
I am not sure how appropriate is this question, but -
I am curious about how the compiler sets memory aside for an object (allocation of memory) even before it is constructed (before even the constructor is called!).
How does it happen for primitive datatypes?
This sounds a bit naive, but what exactly is it ?
Is it entirely a run time process, or does it (the compiler) have any plans like to do this, to do that, during run-time, which it decides before hand during the compile- time. I have no idea at all!
An object, be it a primitive type, a pointer, or a instance of a big class, occupies a certain known amount of memory. That memory must somehow be set aside for the object. In some circumstances, that set-aside memory is initialized. That initialization is what constructors do. They do not set aside (or allocate) the memory needed to store the object. That step is performed before the constructor is called.
In other words, when does the memory allocation for literally ANY kind of variable happen, in terms of time, at which point? At which step in compilation (or run-time)?
Memory allocation always happens at run time. Memory reservation, for objects that reside on the stack, or for static variables, happens at compile time (or at run time for C99 VLAs).
Memory for an object's members is always in place before the constructor runs. It is the job of the compiler and its runtime support to ensure that is so.
Allocation objects created with new or new[] or some variant is done at runtime, by accessing the freestore and finding enough space to place the new object, prior to the constructor running.
Allocation for local objects within a function are done at runtime. However, this is usually accomplished by moving a stack pointer the correct size of bytes, and the space between the previous value and the new value is now reserved for the object. The constructors are run after the space is run.
Allocation for global and static objects are done at compile time by the compiler, and their constructors are run when the translation unit they are defined in is loaded (usually before main() begins executing).
Allocation for objects contained directly (not via pointer) within another object is done as part of the allocation for that object.
There's (loosely speaking) three typical scenarios: allocation on the stack, allocation from heap, and static allocation.
The first is what happens whenever you declare a local variable within a function:
void foo ( )
{
int bar = 42;
}
Here, the memory for bar is allocated on the stack. It is allocated at the time foo is called.
The second scenario happens when you create a class instance with the new operator:
void foo ( )
{
MyClass* bar = new MyClass( );
}
Here, the memory for i is allocated on the heap. This again happens at runtime, and occurs as the new operator executes. It works essentially in the same manner a C's malloc, if you're more familiar with that.
Finally, there's static allocation.
void foo ( )
{
static int bar = 42;
}
Here, the compiler knows ahead of time that memory will be needed for bar, and so it inserts into the executable an instruction telling the executable loader to reserve space, or literally makes a space in the executable for the variable to reside in. The memory for bar is therefore typically still allocated at runtime, as the executable loads.
how can we clean the stack...
return statement is used to go out from the function. now
if (m1.high_[0] < m2.low_[0]) return FALSE;
here it have m1 and m2 two points with high[0],low[0], low[1] and high[1] values..
now if we use return with statement than is this clean the stack.. i mean return statement with if condition is used to clean the stack.. is it?
You dont really "clean" the stack. All that happens is the stack pointer is reset to top of the calling programs stack storage.
Any subsequent function called from this program will be given the same stack pointer as your program receieved (including any values set by your program -- which is why its important to intialise automatic storage!)
Conversly when your program invokes a function the called function will be given a stack pointer of just after the last piece of your stack, and, if you call more than one function they will all end up with the same stack pointer.
To clarify C C++ programs support three types of storage allocation:-
"static" which is effectivly global to the compile unit. A suitable lump of storage is allocated when the main program starts and each "static" is allocated an address in this lump of starage. Which is used until the main program terminates.
"heap" this is a collection of storage areas managed by "malloc" with a little help from the underlying operating system. Most (but not all!) "new" objects allicate memory this way.
Then "automatic" storage (which is the default) uses the stack. Again this is fairly large contiguous area of storage allocated whne your main program starts. Any automatic variables used by "main" will be allocated to the begining of the stack and the stack pointer incremented to point to the word after the end of main's last variable.
When the first function is called it allocates its automatic variables starting from the current stack pointer and the stck pointer is set to the word after the end of its last variable, if if calls other functions then the process is repeated. When a function ends the stack pointer is reset to whatever value it had when the function was called.
In this way storage is constantly reused without the need for any mallocs or frees and it makes it easy to implement recursive functions as each call will get its own piece fo the stack (until the stack runs out!).
Yes, whenever a function returns by executing 'return XXXX', the stack frame for the concerned function is removed. Local automatic storage duration objects are destroyed in this process. Also it may involve manipulation of certain CPU registers (e.g. ESP, EBP on Intel) and is an implementation specific behavior. It does not matter if the return statement is executed in a condition or on the value which is being returned
EDIT 2:
In the code below, the local object 's' (which has automatic storage duration) is destroyed. The local object 'p' and 'x' are also destroyed, but the memory pointed to by 'p' which was newe'd is not deleted automatically until explicitly deleted is done (using delete). All this happens irrespective of when the function 'f' returns via 'return true' or 'return false'
struct S{};
bool f(int x){
S s;
S *p = new S;
if(x == 2) return true;
else return false;
}