Reputation:
Is there a function in C/C++ that can get rid of non-dynamical data, similar to function free();
for dynamically allocated memory.
I tried using function free(i);
but the compiler reported an error :
invalid conversion from 'int' to 'void*' [-fpermissive]
In the following code I used free(&i);
, compiler didn't report an error, but also it didn't free the memory.
#include<iostream>
#include<stdlib.h>
int main()
{
int i, n;
cin >> n;
for(i = 0; i < n; i++);
cout << i << endl;
free(&i);
cout << i << endl;
return 0;
}
For input 15
output is:
15
15
Process returned 0 (0x0) execution time : 11.068 s
Press any key to continue.
And I got a warning from the compiler:
warning: attempt to free a non-heap object 'i' [-Wfree-nonheap-object]
Upvotes: 1
Views: 1486
Reputation: 13240
I'll add a beginner level answer to the set of advanced answers around here in case an actual novice stumbles upon the question:
You don't need to free data structures on the stack and - as Deduplicator has pointed out - you are not allowed to either. Except for some special cases all data that is not dynamically allocated (e.g. via new) is placed on the stack by the compiler. The stack is a memory section of your program at run time that grows with every function call and shrinks with every function exit. It is divided in so called stack frames that provide the local memory of your function. At compile time the compiler finds out how much memory a function needs - in your example that would be 8 bytes for two 4 byte integers (assuming you are compiling to a 32bit target) - and produces instructions that create a large enough stack frame for all local variables to reside in when the function is called. There is a way, though, to tell the compiler that you only need a variable for limited amount of time inside your function: Scopes, which are created by curly braces - as niklasfi has pointed out. An example:
int foo() {
int outerScopeVariable = 5;
{
int innerScopeVariableA = 8;
}
{
int innerScopeVariableB = 20;
}
}
The variable innerScopeVariableA
will only "live" in the curly braces that surround it. On a high level that means you cannot refer to it in scopes that are outside the {}
block it has been declared in and for classes at the end of the block the destructor of the object is called. On a low level the compiler knows that at the end of the block the memory reserved for innerScopeVariableA
is no longer needed. As it is stack memory though it can not free it in the way dynamic memory can be freed. Remember, the stack memory is only discarded at the end of the function. But what it can instead do is reuse the memory of innerScopeVariableA
for innerScopeVariableB
. So for foo
an optimizing compiler can actually come by with only 8 bytes of stack memory.
For more information about the stack and the heap (this is where dynamic memory is allocated) you can look at this question: What and where are the stack and heap? . An in depth discussion of the stack can be found here: http://www.altdevblogaday.com/2011/12/14/c-c-low-level-curriculum-part-3-the-stack/
Edit: You can actually observe this stack memory reuse if you put big data structures on the stack. Running the following code compiled with g++ 4.8.1 your output is 123987
.
#include <iostream>
using namespace std;
void foo() {
{
int a[1024];
a[0] = 123987;
}
{
int b[1024];
cout << b[0] << endl;
}
}
int main() {
foo();
return 0;
}
Looking at the binary g++ reserves 4136 bytes for foo on the stack, 4096 of which are necessary for one integer array with 1024 elements (I've compiled for a 32bit target). The little bit of extra space has probably something to do with memory alignments. You can also observe this effect by printing the memory addresses, here is an example using an online compiler: http://codepad.org/r5S1hvtV .
Upvotes: 3
Reputation: 31519
I won't go into manually calling the destructor because that's bad practice unless the object was constructed using an overloaded form of operator new()
, except when using the std::nothrow
overloads.
A common idiom to get rid of stack memory (and technichally qualify as an answer to your question) is to swap it with a default constructed temporary
MyType t1;
std::swap(t1, MyType());
The second line swaps your instance with a temporary, so the original instance gets destructed at that line.
Now, you are still left with an instance in the stack so there are 2 cases this would have a meaning
t1
to be called at that line (as if getting rid of the stack object)Upvotes: 1
Reputation: 45664
Always use the deallocation method which complements the allocation method.
For stack variables, that means exiting the block, maybe even the function.
Otherwise you get Undefined Behavior, so everything can happen.
In your example, free()
seems to either
For debugging, a noisy crash or at least obvious misbehaviour would be preferable, but cannot be guaranteed.
Upvotes: 3
Reputation: 15931
You can just enclose your code in brackets {}
. Any object lives on the stack until the surrounding brackets close. E.g.
int b;
{
int a;
} // a gets destroyed, b is still alive
As Deduplicator states, usually, you don't need to take care of the destruction of your variables, as your compiler does that for you.
Upvotes: 1