When is memory deallocated in c? - c

I am trying to find out when memory used for variables in c is freed. As an example, when would the integer i be freed in the following code snippet?
int function()
{
int i = 1;
// do some things
return 0;
}

In C, as in all other languages, lexically scoped variables, such as i here, are only valid within their scopes -- the scope of i is from its declaration through the closing brace of the function. When exactly they are freed is often not specified, but in practical C implementations local variables are allocated on the call stack and their memory is reused once the function returns.
Consider something like
int function()
{
int i; // beginning of i's scope
{
int j; // beginning of j's scope
...
} // end of j's scope
{
int k; // beginning of k's scope
...
} // end of k's scope
return 0; // all locals of the function are deallocated by the time it is exited
} // end of i's scope
Scope determines when the variables can be accessed by name and, for local (auto) variables, when their content can be validly accessed (e.g., if you set a pointer to the address of a local variable, dereferencing the pointer outside the variable's scope is undefined behavior). Deallocation is a somewhat different matter ... most implementations won't do anything at the end of j or k's scope to "deallocate" them, although they will likely reuse the same memory for both variables. When function returns, most implementations will "pop" all locals off the stack, along with the return address, by a single decrement of the stack pointer, in effect "deallocating" their memory ... although the memory is still right there on the stack, ready to be "allocated" to the next function that is called.
Note that the terminology of your question is somewhat confused ... variables have scope, but it's memory, not variables, that is allocated and deallocated. Some variables may not even have any memory allocated for them if, for instance, they are constants or are never used in the program. And only the memory for local variables is allocated or freed as described above ... the memory for static and file scope variables is never freed, and only allocated when the program is loaded. And there is other memory -- heap memory -- that is explicitly allocated and freed by your program (via calls to malloc/realloc/calloc/strdup/free etc.). But although heap memory can be referenced by pointer variables, the memory for the pointer variables themselves consists just of the reference (memory address), with the variables having either local or static/file scope.

It will be freed when it goes out of scope. Since it has function scope, this will happen when the function returns.

i is allocated on the stack. It is freed when return is executed.

Automatic variables are local to a scope in C:
A scope is basically marked by '{' '}' so when you are inside a {} pair you are inside a scope. Of course scopes can be nested.
This is why in older C standard the local variables had to be defined at the top of a scope because it made writing the C compiler easier (the compiler would see a '{' and then all the variables and then statements) so it knew the variables it had to deal with. This changed in C99 (I think?) and later on where you can define variables anywhere in between statements.
This can be quite helpful of course:
int foo()
{
int k = 0; /* inside the scope of foo() function */
for(; k < 10; k++) { /* don't need k = 0; here we set it to zero earlier */
int i = 1; /* initialize inside the scope of the for loop */
i = i * 2; /* do something with it */
printf ("k = %d, i = %d\n", k, i);
}
#if 0
printf ("i = %d\n", i); /* would cause an unknown identifier error
* because i would be out of scope, if you changed
* #if 0 to #if 1
*/
#endif
return 0;
}
int main()
{
foo();
foo();
return 0;
}
Notice that i = 2 all the time for the iterations of the loop in foo()
A more fun thing to see is how the keyword static modifies the persistence of the variable.
int bar()
{
int k = 0; /* inside the scope of bar() function */
for(; k < 10; k++) { /* don't need k = 0; here we set it to zero earlier */
static int i = 1; /* initialize inside the scope of the for loop */
i = i * 2; /* do something with it */
printf ("k = %d, i = %d\n", k, i);
}
#if 0
printf ("i = %d\n", i); /* would cause an unknown identifier error
* because i would be out of scope, if you changed
* #if 0 to #if 1
*/
#endif
return 0;
}
int main()
{
foo();
foo();
return 0;
}
Note the changes and note how a static variable is treated.
What would happen to the for loop if you put the keyword static in front of int k = 0; ?
Interesting uses
C macros are very useful. Sometimes you want to define a complicated local macro rather than a function for speed and overall simplicity. In a project I wanted to manipulate large bit maps, but using functions to perform 'and' 'or' 'xor' operations was a bit of a pain. The size of bitmaps was fixed so I created some macros:
#define BMPOR(m1, m2) do { \
int j; \
for (j = 0; j < sizeof(bitmap_t); j++ ) \
((char *)(m1))[j] |= ((char *)(m2))[j]; \
} while (0)
the do { } while(0) is a fun trick to let a scoped block be attached to if/for/while etc. without an issue, the block executes exactly once (since the while is checked at the END of the block), and when compiler sees while(0) it just removes the loop; and of course this lets you put a semi-colon at the end so IDEs and you (later) don't get confused about what it is.
The macro above was used as under:
int foo()
{
bitmap_t map_a = some_map(), map_b = some_other_map();
BITOR(map_a, map_b); /* or map_a and map_b and put the results in map_a */
}
here the do {} while(0) allowed a local scope with a local variable j, a for loop and anything else that I might have needed.

Variable gets deallocated when the variable gets out of scope.In your code variable i will get deallocated after return 0 statement is executed.
You can find more on variable scope here

Related

How many times called the function calculate? İn C

I have one question.
I want to write a program with fibonacci, but i have a problem.
"Every time the function is called from the main function, it should print out how many times it has been called"
I try add counter, but every time counter is 1. Thx
You should use the static variable or you can pass the count variable for each call. The below one is for static variable case
#include<stdio.h>
int fib(int n)
{ static int count = 0;
count++;
printf("%d", count);
if (n <= 1)
return n;
return fib(n-1) + fib(n-2);
}
int main ()
{
int n = 9;
printf("%d", fib(n));
getchar();
return 0;
}
Your initial attempt of adding a counter and it always being 1 tells me that you're a beginner. One very important concept you will need to get a handle on is "scope". When you create a local variable in a function, the variable gets allocated from the stack each time the function is called and is considered "in scope" for the duration of the function until you return. When you return from the function, the memory allocated for the variable is released and is no longer considered "in scope". Without specifically telling the compiler that you want the variable to hang around (using the static keyword), you are not guaranteed to get the same chunk of memory, and even if you did get the same chunk of memory, it's very likely that some other function has used it and destroyed whatever value was there.
So to answer your question specifically, you should use the static keyword in the variable declaration for your counter such as static int counter = 0; with an initial value of 0.

Declaring memory on stack overwrites previously declared memory

How can I allocate memory on the stack and have it point to different memory addresses so I can use it later? For example. this code:
for (int i = 0; i < 5; i++) {
int nums[5];
nums[0] = 1;
printf("%p\n", &nums[0]);
}
Will print out the same address every time. How can I write memory to stack (not the heap, no malloc) and have it not overwrite something else that's on the stack already.
You could use alloca to allocate a different array from the runtime stack for each iteration in the loop. The array contents will remain valid until you exit the function:
#include <stdlib.h>
#include <stdio.h>
void function() {
for (int i = 0; i < 5; i++) {
int *nums = alloca(5 * sizeof(*nums));
nums[0] = 1;
printf("%p\n", (void *)nums);
/* store the value of `num` so the array can be used elsewhere.
* the arrays must only be used before `function` returns to its caller.
*/
...
}
/* no need to free the arrays */
}
Note however that alloca() is not part of the C Standard and might not be available on all architectures. There are further restrictions on how it can be used, see the documentation for your system.
I believe you are looking for:
a way to control how memory is being allocated on the stack, at least in the context of not overwriting already-used memory
Of course, that's taken care by the OS! The low level system calls will make sure that a newly created automatic variable will not be written upon an already used memory block.
In your example:
for (int i = 0; i < 5; i++) {
int nums[5];
...
}
this is not the case, since nums will go out of scope, when the i-th iteration of the for loop terminates.
As a result, the memory block nums was stored into during the first iteration, will be marked as free when the second iteration initiates, which means that when nums of the first iteration is going to be allocated in the stack, it will not be aware of any existence of the nums of the first iteration, since that has gone already out of scope - it doesn't exist!

Memory allocation and changing values

I am very new to C so sorry in advance if this is really basic. This is related to homework.
I have several helper functions, and each changes the value of a given variable (binary operations mostly), i.e.:
void helper1(unsigned short *x, arg1, arg2) --> x = &some_new_x
The main function calls other arguments arg3, arg4, arg5. The x is supposed to start at 0 (16-bit 0) at first, then be modified by helper functions, and after all the modifications, should be eventually returned by mainFunction.
Where do I declare the initial x and how/where do I allocate/free memory? If I declare it within mainFunc, it will reset to 0 every time helpers are called. If I free and reallocate memory inside helper functions, I get the "pointer being freed was not allocated" error even though I freed and allocated everything, or so I thought. A global variable doesn't do, either.
I would say that I don't really fully understand memory allocation, so I assume that my problem is with this, but it's entirely possible I just don't understand how to change variable values in C on a more basic level...
The variable x will exist while the block in which it was declared is executed, even during helper execution, and giving a pointer to the helpers allows them to change its value. If I understand your problem right, you shouldn't need dynamic memory allocation. The following code returns 4 from mainFunction:
void plus_one(unsigned short* x)
{
*x = *x + 1;
}
unsigned short mainFunction(void)
{
unsigned short x = 0;
plus_one(&x);
plus_one(&x);
plus_one(&x);
plus_one(&x);
return x;
}
By your description I'd suggest declaring x in your main function as a local variable (allocated from the stack) which you then pass by reference to your helper functions and return it from your main function by value.
int main()
{
int x; //local variable
helper(&x); //passed by reference
return x; //returned by value
}
Inside your helper you can modify the variable by dereferencing it and assigning whatever value needed:
void helper(int * x)
{
*x = ...; //change value of x
}
The alternative is declaring a pointer to x (which gets allocated from the heap) passing it to your helper functions and free-ing it when you have no use for it anymore. But this route requires more careful consideration and is error-prone.
Functions receive a value-wise copy of their inputs to locally scoped variables. Thus a helper function cannot possibly change the value it was called with, only its local copy.
void f(int n)
{
n = 2;
}
int main()
{
int n = 1;
f(n);
return 0;
}
Despite having the same name, n in f is local to the invocation of f. So the n in main never changes.
The way to work around this is to pass by pointer:
int f(int *n)
{
*n = 2;
}
int main()
{
int n = 1;
f(&n);
// now we also see n == 2.
return 0;
}
Note that, again, n in f is local, so if we changed the pointer n in f, it would have no effect on main's perspective. If we wanted to change the address n in main, we'd have to pass the address of the pointer.
void f1(int* nPtr)
{
nPtr = malloc(sizeof int);
*nPtr = 2;
}
void f2(int** nPtr)
{
// since nPtr is a pointer-to-a-pointer,
// we have to dereference it once to
// reach the "pointer-to-int"
// typeof nPtr = (int*)*
// typeof *nPtr = int*
*nPtr = malloc(sizeof int);
// deref once to get to int*, deref that for int
**nPtr = 2;
}
int main()
{
int *nPtr = NULL;
f1(nPtr); // passes 'NULL' to param 1 of f1.
// after the call, our 'nPtr' is still NULL
f2(&nPtr); // passes the *address* of our nPtr variable
// nPtr here should no-longer be null.
return 0;
}
---- EDIT: Regarding ownership of allocations ----
The ownership of pointers is a messy can of worms; the standard C library has a function strdup which returns a pointer to a copy of a string. It is left to the programmer to understand that the pointer is allocated with malloc and is expected to be released to the memory manager by a call to free.
This approach becomes more onerous as the thing being pointed to becomes more complex. For example, if you get a directory structure, you might be expected to understand that each entry is an allocated pointer that you are responsible for releasing.
dir = getDirectory(dirName);
for (i = 0; i < numEntries; i++) {
printf("%d: %s\n", i, dir[i]->de_name);
free(dir[i]);
}
free(dir);
If this was a file operation you'd be a little surprised if the library didn't provide a close function and made you tear down the file descriptor on your own.
A lot of modern libraries tend to assume responsibility for their resources and provide matching acquire and release functions, e.g. to open and close a MySQL connection:
// allocate a MySQL descriptor and initialize it.
MYSQL* conn = mysql_init(NULL);
DoStuffWithDBConnection(conn);
// release everything.
mysql_close(conn);
LibEvent has, e.g.
bufferevent_new();
to allocate an event buffer and
bufferevent_free();
to release it, even though what it actually does is little more than malloc() and free(), but by having you call these functions, they provide a well-defined and clear API which assumes responsibility for knowing such things.
This is the basis for the concept known as "RAII" in C++

Variable scope inside while loop

This is perhaps one of the most odd things I've ever encountered. I don't program much in C but from what I know to be true plus checking with different sources online, variables macroName and macroBody are only defined in scope of the while loop. So every time the loop runs, I'm expecting marcoName and macroBody to get new addresses and be completely new variables. However that is not true.
What I'm finding is that even though the loop is running again, both variables share the same address and this is causing me serious headache for a linked list where I need to check for uniqueness of elements. I don't know why this is. Shouldn't macroName and macroBody get completely new addresses each time the while loop runs?
I know this is the problem because I'm printing the addresses and they are the same.
while(fgets(line, sizeof(line), fp) != NULL) // Get new line
{
char macroName[MAXLINE];
char macroBody[MAXLINE];
// ... more code
switch (command_type)
{
case hake_macro_definition:
// ... more code
printf("**********%p | %p\n", &macroName, &macroBody);
break;
// .... more cases
}
}
Code that is part of my linked-list code.
struct macro {
struct macro *next;
struct macro *previous;
char *name;
char *body;
};
Function that checks if element already exists inside linked-list. But since *name has the same address, I always end up inside the if condition.
static struct macro *macro_lookup(char *name)
{
struct macro *temp = macro_list_head;
while (temp != NULL)
{
if (are_strings_equal(name, temp->name))
{
break;
}
temp = temp->next;
}
return temp;
}
These arrays are allocated on the stack:
char macroName[MAXLINE];
char macroBody[MAXLINE];
The compiler has pre-allocated space for you that exists at the start of your function. In other words, from the computer's viewpoint, the location of these arrays would the same as if you had defined them outside the loop body at the top of your function body.
The scope in C merely indicates where an identifier is visible. So the compiler (but not the computer) enforces the semantics that macroName and macroBody cannot be referenced before or after the loop body. But from the computer's viewpoint, the actual data for these arrays exists once the function starts and only goes away when the function ends.
If you were to look at the assembly dump of your code, you'd likely see that your machine's frame pointer is decremented by a big enough amount for your function's call stack to have space for all of your local variables, including these arrays.
What I need to mention in addition to chrisaycock's answer: you should never use pointers to local variables outside function these variables were defined in. Consider this example:
int * f()
{
int local_var = 0;
return &local_var;
}
int g(int x)
{
return (x > 0) ? x : 0;
}
int main()
{
int * from_f = f(); //
*from_f = 100; //Undefined behavior
g(15); //some function call to change stack
printf("%d", *from_f); //Will print some random value
return 0;
}
The same, actually, applies to a block. Technically, block-local variables can be cleaned out after the block ends. So, on each iteration of a loop old addresses can be invalid. It will not be true since C compiler indeed puts these vars to the same address for perfomance reasons, but you can not rely on it.
What you need to understand is how memory is allocated. If you want to implement a list, it is a structure that grows. Where does the memory come from? You can not allocate much memory from the stack, plus the memory is invalidated once you return from a function. So, you will need to allocate it from the heap (using malloc).

Variable reuse in C

The code I'm looking at is this:
for (i = 0; i < linesToFree; ++i ){
printf("Parsing line[%d]\n", i);
memset( &line, 0x00, 65 );
strcpy( line, lines[i] );
//get Number of words:
int numWords = 0;
tok = strtok(line , " \t");
while (tok != NULL) {
++numWords;
printf("Number of words is: %d\n", numWords);
println(tok);
tok = strtok(NULL, " \t");
}
}
My question centers around the use of numWords. Does the runtime system reuse this variable or does it allocate a new int every time it runs through the for loop? If you're wondering why I'm asking this, I'm a Java programmer by trade who wants to get into HPC and am therefore trying to learn C. Typically I know you want to avoid code like this, so this question is really exploratory.
I'm aware the answer is probably reliant upon the compiler... I'm looking for a deeper explanation than that. Assume the compiler of your choice.
Your conception about how this works in Java might be misinformed - Java doesn't "allocate" a new int every time through a loop like that either. Primitive type variables like int aren't allocated on the Java heap, and the compiler will reuse the same local storage for each loop iteration.
On the other hand, if you call new anything in Java every time through a loop, then yes, a new object will be allocated every time. However, you're not doing that in this case. C also won't allocate anything from the heap unless you call malloc or similar (or in C++, new).
Please note the difference between automatic and dynamic memory allocation. In Java only the latter exists.
This is automatic allocation:
int numWords = 0;
This is dynamic allocation:
int *pNumWords = malloc(sizeof(int));
*pNumWords = 0;
The dynamic allocation in C only happens explicitly (when you call malloc or its derivatives).
In your code, only the value is set to your variable, no new one is allocated.
From a performance standpoint, it's not going to matter. (Variables map to registers or memory locations, so it has to be reused.)
From a logical standpoint, yes, it will be reused because you declared it outside the loop.
From a logical standpoint:
numWords will not be reused in the outer loop because it is declared inside it.
numWords will be reused in the inner loop because it isn't declared inside.
This is what is called "block", "automatic" or "local" scope in C. It is a form of lexical scoping, i.e., a name refers to its local environment. In C, it is top down, meaning that it happens as the file is parsed and compiled and visible only after defined in the program.
When the variable goes out of scope, the lexical name is no longer valid (visible) and the memory may be reused.
The variable is declared in a local scope or a block defined by curly braces { /* block */ }. This defines a whole group of C and C99 idioms, such as:
for(int i=0; i<10; ++i){ // C99 only. int i is local to the loop
// do something with i
} // i goes out of scope here...
There are subtleties, such as:
int x = 5;
int y = x + 10; // this works
int x = y + 10;
int y = 5; // compiler error
and:
int g; // static by default and init to 0
extern int x; // defined and allocated elsewhere - resolved by the linker
int main (int argc, const char * argv[])
{
int j=0; // automatic by default
while (++j<=2) {
int i=1,j=22,k=3; // j from outer scope is lexically redefined
for (int i=0; i<10; i++){
int j=i+10,k=0;
k++; // k will always be 1 when printed below
printf("INNER: i=%i, j=%i, k=%i\n",i,j,k);
}
printf("MIDDLE: i=%i, j=%i, k=%i\n",i,j,k); // prints middle j
}
// printf("i=%i, j=%i, k=%i\n",i,j,k); compiler error
return 0;
}
There are idiosyncrasies:
In K&R C, ANSI C89, and Visual Studio, All variables must be declared at the beginning of the function or compound statement (i.e., before the first statement)
In gcc, Variables may be declared anywhere in the function or compound statement and is only visible from that point on.
In C99 and C++, Loop variables may be declared in for statement and are visible until end of loop body.
In a loop block, the allocation is performed ONCE and the RH assignment (if any) is performed each time.
In the particular example you posted, you enquired about int numWords = 0; and if a new int is allocated each time through the loop. No, there is only one int allocated in a loop block, but the right hand side of the = is executed every time. This can be demonstrated so:
#include <stdio.h>
#include <time.h>
#include <unistd.h>
volatile time_t ti(void){
return time(NULL);
}
void t1(void){
time_t t1;
for(int i=0; i<=10; i++){
time_t t2=ti(); // The allocation once, the assignment every time
sleep(1);
printf("t1=%ld:%p t2=%ld:%p\n",t1,(void *)&t1,t2,(void *)&t2);
}
}
Compile that with any gcc (clang, eclipse, etc) compatible compiler with optimizations off (-O0) or on. The address of t2 will always be the same.
Now compare with a recursive function:
int factorial(int n) {
if(n <= 1)
return 1;
printf("n=%i:%p\n",n,(void *)&n);
return n * factorial(n - 1);
}
The address of n will be different each time because a new automatic n is allocated with each recursive call.
Compare with an iterative version of factorial forced to used a loop-block allocation:
int fac2(int num) {
int r=0; // needed because 'result' goes out of scope
for (unsigned int i=1; i<=num; i++) {
int result=result*i; // only RH is executed after the first time through
r=result;
printf("result=%i:%p\n",result,(void *)&result); // address is always the same
}
return r;
}
In conclusion, you asked about int numWords = 0; inside the for loop. The variable is reused in this example.
The way the code is written, the programmer is relying on the RH of int numWords = 0; after the first to be executed and resetting the variable to 0 for use in the while loop that follows.
The scope of the numWords variable is inside the for loop. Just as Java, you can only use the variable inside the loop, so theoretically its memory would have to be freed on exit - since it is also on the stack in your case.
Any good compiler however would use the same memory and simply re-set the variable to 0 on each iteration.
If you were using a class instead of an int, you would see the destructor being called every time the for loops.
Even consider this:
class A;
A* pA = new A;
delete pA;
pA = new A;
The two objects created here will probably reside at the same memory.
It will be allocated every time through the loop (the compiler can optimize out that allocation)
for (i = 0; i < 100; i++) {
int n = 0;
printf("%d : %p\n", i, (void*)&n);
}
No guarantees all 100 lines will have the same address (though probably they will).
Edit: The C99 Standard, in 6.2.4/5 says: "[the object] lifetime extends from entry into the block with which it is associated until execution of that block ends in any way." and, in 6.8.5/5, it says that the body of a for statement is in fact a block ... so the paragraph 6.2.4/5 applies.

Resources