Returning variables - c

Here I have a basic doubt. Here it says that I need not to return global variables.
Now, I am wondering, if I return a global variable (let it be char or int or some other data type), what horrid does it cause?
I know that, when I return a variable from a function, the variable is destroyed immediately.
Does it mean, the memory allocated to that variable is de-allocated/freed?
Can someone please shed some light?
Consider the following code:
#include<stdio.h>
int var; //a global int
int MyFuction(void)
{
int temp_var = 0;
temp_var++;
return temp_var; //it will get destroyed after returning
}
int main(void)
{
MyFunction();
var++;
return var; //Will it get destroyed here, (var being a global variable)?
}

var is gloabl variable it doesn't destroyed after return statement, its life is till program executes and scope is every where in code.
Only variable local to functions goes out-of-scope and destroyed after return statement.
Note: There is two things life and scope.
Life of local variable is till function returns. And scope is within function its memory comes from stack.
Life of global varialbs is till program terminates and scope is every where in C.

int main(void)
{
MyFunction();
var++;
return var; //Will it get destroyed here, (var being a global variable)?
}
No, it won't. Objects with static storage duration (like var here) are destroyed at program termination.

the global variable will not get destroyed as they have a lifetime(the time till they are accessible) is that of the whole program.

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.

How to have a global variable in C that increments when used by any function

I am attempting to have a gobal counter the can can used by any function in the program. Is this possible?
int* count;
main(){
*count = 0;
}
void incrementCount(){
++*count;
}
int getCount(){
return *count;
}
If not possible how can I do something similar?
No need to take a pointer. Take a Variable like
int count;
If you are going to use it in a single file better to declare it static.
A much better approach would be using the getter and setter functions instead of updating global variable everywhere
I am attempting to have a gobal counter the can can used by any function in the program. Is this possible?
Yes, even though it's not a good thing to use global variable.
All you need to do is to declare the function in global scope. You should also initialise it in main before any function call.
int count;
int main()
{
count = 0;
incrementCount();
...
}
There is no need to use pointer in your case. And it's wrong as well, because you have not allocate any memory for that pointer.
Firstly there are few issues in the shared code sample. Here
int* count; /* count is pointer i.e you need to make count to hold or point to some valid memory location */
count is of int pointer type. And here
*count = 0; /* de-referencing uninitiated pointer */
you are trying to de-reference count which has not valid memory. It causes segmentation fault. Before de-referencing you need to allocate memory. for e.g
count = malloc(sizeof(*count));
/* error handling of malloc return value */
*count = 0;
I am attempting to have a gobal counter the can can used by any
function in the program ?
You can do the same task without using pointer, try using static if use having file scope. If possible avoid using global variable.
You can just declare the variable as integer (not pointer).
You can have a global getter and setter function. Also initialize the global variable before any function call, best will be in Main().
first, you can't do
*count = 0;
if you don't have initialised your pointer, it means refrenced to a
variable like:
count = &x;
Then, if you want that variable is shared and the value is always
updated between methods you can simply declare the variable as
"static",
#include <stdio.h>
static int count;
main(){
printf("%d",count);
}
void incrementCount(){
++count;
}
int getCount(){
return count;
}

Calling a function without losing that data that the function had before?

I picked up the bad habit of Global Variables early on, So ive been trying to distance myself by using local variables and learning call by reference/value which isn't so bad until I run into a problem like this, say I have a function Menu() which contains a main menu, and an array, then from the Menu I'd go to a function and do stuff with the Array, now I usually get stuck here my functions are usually of void type, but usually for my programs I use a if selection to get back to the Menu, like If(userinput ==2){Menu();} usually this causes two problems 1. When I enter Menu it resets all the variable values
2.If i have this function in multiple places it will start giving me parameter errors.
These problems discourage me and make me lean towards the side of Global Variables.
Example:
menu(){
int array[100];
functionadd(array);
}
functionadd(array[])
{
int userinput;
do{
//lets the just say here the program does things to my array.
// usually when I want to go back to the menu I'd do something like this
printf("Again or back to menu?1(Again) or 2(Menu)")
scanf_s("%d%[^\n]", &userinput); '\n'==getchar();
} while(userinput == 1)
if(userinput != 2){Menu();} /*this would bring me back to
the menu but my array would be back to as its original state
when it was called in Menu I understand why this happens I
just need to learn how to counter act it*/
}
Some pseudo code to not have a variable to be "reset" with static keyword:
int Menu(){
static int remember = 0;
remember++;
return remember;
}
int main(){
printf("remember = %d\n", Menu());
printf("remember = %d\n", Menu());
printf("remember = %d", Menu());
}
output:
remember = 1
remember = 2
remember = 3
Notice that a global variable is, like Ron says, is a variable for the lifetime of the program. So is a static variable, but in this case it isn't accessible in another function. Also, a static variable isn't really thread safe
"All non-local state must be accessed through atomic operations and
the data-structures must also be reentrant."
Well, You're calling is something like this:
main()
{
menu();
}
menu()
{
yourfunction();
}
yourfunction()
{
if(userinput==2)
menu();
}
Here, you can observe that you're again calling menu() but not returning back..
If you're at the depth in menu(), if you'll exit, will return to yourfunction() but not the main().
I'll recommend you to use codes similar to the following:
menu()
{
do
{
yourfunction();//call your function
//after the completion ask to continue
printf("Do you want to continue? (Y/N) ");
fflush(stdin);
scanf(" %c",&choice);
}while(choice=='y'||choice=='Y');
}
void yourfunction()
{
//do only functional job
}
This will help you to return to the menu() and ask you for the continuation.
And also the values will remain as you want them to.
Edit:
Or if you want to stick to your habit of programming.
Simply tell the program what to do when user input is 1 (i.e. not equal to 2)
And don't define anything when 2 is input.
It will automatically return to menu()
menu()
{
yourfunction();
}
Yourfunction()
{
if(userinput==1)
{
// do this
}
}
Or other way:
menu()
{
yourfunction();
}
Yourfuntion()
{
if(userinput!=2)
{
//do this
}
}
If the function gets userinput as 2 it will get back to menu().
Over.. :-)
If you save a variable like static you'll not lose the data the function had before, cause the variable won't be destroyed at the end if the function and the stack won't be cleaned. Example:
static int var=0;
var++;
return var;
If you call the function 10 times the variable will be increased ten times.
You should take note of the following:
In C, all parameters are passed using call by value.
When you passing an array as parameter to a function, it decays as a pointer to the first element of the array.
Call by value doesn't mean you can't modify some function's local variable from another function. For that, you pass a pointer as parameter and then from the callee function assign value to its dereferenced stated.
eg:
void f(int *c)
{
*c = 7;
}
int main(void)
{
int count = 4;
f(&count);
printf("%d", count);
return 0;
}
The reason people discourage overuse of global variables is because those variables will be taking memory for the life of the program (process really).
But, in this specific case, that's the behavior you want. You want to remember the state of the menu between calls, and you can either implement a structure yourself and save the state in the calling function, or you can simply declare the variable globally.
What irks people is when every variable is global, regardless of whether they need to be. In a language like C, which basically only survives because of its ability to manually manage memory to the utmost efficiency, it hurts our brains to see people wasting it. In general, it's a code smell to see any global variables that aren't constants. As a commenter has pointed out, there are other reasons to avoid using globals. Rather than iterate through them all, I'll leave this here: why globals are bad
Note, I'm not trying to be mean, just not sure which of those pages is the best resource, so I gave OP all of them.
Edit: a few other points. You also could easily accomplish what you need by either passing a pointer containing the value you may or may not edit within the function as a parameter, but the solution I would probably implement given what you've said is like this:
int choice = menu();
case (choice ):
//logic here

When is memory deallocated in 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

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).

Resources