I need to declare a variable that is not in the stack memory but in the heap, like below
struct mystruct *name;
Should I declare it outside all functions (even outside main()) at the begin of file?
Please note that a variable is never declared "on the heap". Only memory pointed to by a pointer can be allocated on (from) the heap.
In your example, you can declare name indeed outside any function and then it will exist in global memory. You can also delcare the variable inside a function, preceded by the keyword static. This latter will allocate the variable also in global memory, but it will only be visible in the function where you declared it.
To use your pointer variable, you now must alocate memory for it to point to, which you allocate on the heap using malloc.
TL;DR Version
You cannot declare a variable such that the variable itself lives on the heap.
James Michener Version
The C language definition doesn't talk about stacks or heaps; it talks about storage durations.
Objects with auto storage duration (anything declared within a block and without the static keyword) have lifetimes that extend from the beginning of that block and end when the block exits1:
void foo( void )
{
int a = 0; // lifetime of a extends to the end of
// the function
for ( int i = 0; i < 10; i++ ) // lifetime of i and b extend to the end
{ // of the for loop
int b = a + i;
printf( "b = %d\n", b );
}
}
Most implementations allocate storage for auto objects from the hardware stack, because a stack makes that behavior easy to implement2.
Objects with static storage duration (anything declared outside of a function or with the static keyword) have lifetimes that extend from the time the program is loaded into memory until the program exits:
int a = 0; // lifetime of a extends over the lifetime of
// the entire program
int main( void )
{
static int b = 10; // lifetime of b also extends over the lifetime
// of the program, but is only visible within
// main
...
}
Most implementations will set aside storage for static objects within the body of the executable itself (for an executable using the ELF format, such objects will be stored in the .bss, .data, or .rodata sections of the image).
Objects with allocated storage duration (anything allocated with malloc, calloc, or realloc) have lifetimes that extend from the time that they are allocated until they are explicitly deallocated with a call to free.
int *foo( size_t size )
{
int *ptr = malloc( sizeof *ptr * size );
return ptr;
}
void bar( void )
{
int *p = foo( 10 );
// do something with p
free( p );
}
The variables ptr and p only exist for the lifetimes of their respective functions, and they will be typically allocated from the stack. The object both variables point to exists from the time it is allocated with malloc until it is deallocated with free.
Most implementations allocate storage for allocated objects from the heap.
There's really no way for you to declare an object that has allocated storage duration; the only way you can create such an object is via malloc, calloc, or realloc. Whatever object you declare to store the pointer value returned by any of those functions will have either auto or static storage duration.
1. In practice, storage for all local objects is allocated at function entry and released at function exit, regardless of whether the object's lifetime is over the entire function or limited to a block within the function. However, you should never rely on that storage being accessible outside of that object's lifetime. For example, the lifetimes of i and b are limited to the for loop; even though the storage for each may have been allocated at function entry, you should not attempt to access that storage outside of the loop body.
2. C was designed on a machine with a stack, after all.
Related
This question already has answers here:
Difference between static memory allocation and dynamic memory allocation
(7 answers)
Closed 5 years ago.
I was wondering if someone could explain the differences between the memory allocation for ai and *pai
int ai[10];
int *pai = (int * ) calloc (10, sizeof(int));
I understand the second one is dynamically allocated but im struggling to explain why.
Let's see what is being specified in standard (difference wise)
From 7.22.3.1 (Under Memory management functions)
... The lifetime of an allocated object extends from the allocation
until the deallocation.
So yes, this is for dynamically allocated memory. Their lifetime is different from that of local variables. By calling free they are deallocated. Until then they will be alive. Doesn't depend on the life time of the scope on which they are created.
The first one is having automatic storage duration. This is the primary difference. So in the functions scope where it is declared, when it ends then it's lifetime will be over.
Also some people say that there is a heap and stack - but (un)fortunately C standard doesn't mention it. It is completely implementation of the features expected by the C standard. The implementation can be anything. The differences presented is least bothered about those kind of stuff.
As a conceptual redpill (taken from movie Matrix) pai is of automatic storage duration but the address of the memory it contains is not. The variable pai will be lost when the function where it is defined is executed. But the memory it points to, doesn't.
Well why is it called dynamic allocation?
Know one thing - when in programming we say dynamic in the context of language - it means we are doing something in runtime. Same here, we are allocating some memory when in run time by calling functions like malloc,calloc etc. That's why dynamic allocation.
In the first line, you create a variable of an array type, but the symbol ai is a constant pointer to this variable.
in the second line, you create a pointer type variable. then you allocate an array dynamically with calloc() and you puts it's address in the pointer.
The array ai is allocated on the stack, it implicitly goes out of scope, when the end of the function is reached. The pointer pai points to a memory location, which can be an array or a single element of the type pointed to, the memory is allocated on the heap and must be freed later. The second can be passed back to the function-caller on the end of the function and can even be resized with realloc (realloc does not clear the new memory like calloc does, malloc is like calloc without zeroing out the new memory). The first is for fast array computation and should be in the cache most of the time. The second is for unknown lenght of arrays, when the function is called. When the size is known, many programmers tend to define an array in the caller and pass it to the function, which modifies it. The array is implicitly converted to a pointer when calling the function.
Some library implementations store a pointer to an array in the global section, which can be reallocated. Or they have a fixed length array in global space. These variables are recommended to be thread_local. The user does not have to care about the memorymanagement of the variable of the other library.
library.h
const char* getResourceString(int id);
library.c
thread_local char* string_buf = NULL;
const char* getResourceString(int id) {
int i = getResourceSize(id);
string_buf = realloc(string_buf, i);
// fill the memory
return string_buffer;
};
These are quite different operations:
int ai[10];
declares an array object of 10 ints. If it is declared inside a block, it will have automatic storage duration, meaning that it will vanish at block end (both identifier and data). If it is declared outside any block (at file level) it will have static storage duration and will exist throughout all program.
int *pai = calloc (10, sizeof(int)); // DON'T CAST MALLOC IN C
declares a pointer to an allocated zone of memory that can contains ten integers. You can use pai as a pointer to the first element of an array and do pointer arithmetics on it. But sizeof(pai) is sizeof(int *). The array will have dynamic storage duration meaning that its life will end:
if the allocated block of memory is freed
if it is reused to store other objects
double * pd = pai;
for (int i=1; i<5; i++) { // assuming sizeof(double) == 2 * sizeof(int) here
pd[i] = i; // the allocated memory now contains 5 double
}
So in both case you can use the identifier as pointing to an array of 10 integers, but first one is an integer array object while second one is just a pointer to a block of dynamic memory (memory with no declared type that can take the type of an object that will be copied/created there) .
Gerenally speaking, automatically allocated objects will be on the stack, while dynamically allocated objects will be on the heap. Although this distinction is implementation (not standard) dependent, stack and heap are the most commonly used way to manage memory in C programs. They are basically two distinct regions of memory, the first is dedicated to automatic allocations and the second is dedicated to dynamic allocations. So when you call a function (say, the main function) all the objects declared in the scope of this function will be stacked (automatically allocated in the stack). If some dynamic allocation happens in this function, the memory will be allocated in the heap so that all pointers to this area will be pointing to objects outside the stack. When your function returns, all objects in the stack are also automatically unstacked and virtually don't exist anymore. But all objects in the heap will exist until you deallocate them (or they will be forcefully deallocated by the OS when the program ends). Arrays are structures that can be allocated automatically or dynamically. See this example:
int * automaticFactor() //wrong, see below
{
int x[10];
return &x[0];
}
int * dynamicFactor()
{
int * y = (int *) malloc(sizeof(int) * 10);
return &y[0];
}
int main()
{
//this will not work because &x[0] points to the stack
//and that area will be unstacked after the function return
int * n = automaticFactor();
//this will work because &y[0] points to the heap
//and that area will be in the heap until manual deallocation
int * m = dynamicFactor();
return 0;
}
Note that the pointers themselves are in the stack. What is in the heap is the area they are pointing to. So when you declare a pointer inside a function (such as the y of the example), it will also be unstacked at the end of the function. But since its value (i.e. the address of the allocated area) was returned to a pointer outside the function (i.e. to m), you will not lose track of the area allocated in the heap by the function.
Hi i have code like below , just added logic view not full syntax
int globalVar;
static void* average()
{
void *data = NULL;
if (true)
{
globalVar = getAverage();
data = ((void *)&globalVar);
}
return (data);
}
So my concern is if i return globel variable by assigning to local pointer then will it be in memory or lost when function end?
Thanks,
No there is no memory leak here. Memory leaks only arise from unbalanced malloc and free calls, and there is nothing like that going on here.
(Assuming getAverage() doesn't itself leak).
So my concern is if i return globel variable by assigning to local pointer then will it be in memory or lost when function end?
No.
If it's a global variable then it'll have static storage duration and it won't be "lost" when returning it through a local pointer.
When you access any object through a pointer, what matters is the storage duration of the object you access; not the storage duration of the pointer. So, assuming your global variable has static storage duration (usually defined outside functions at the top of source files), you are fine.
What is the difference between declaring an array "dynamically",
[ie. using realloc() or malloc(), etc... ]
vs
declaring an array within main() with Global scope?,
eg.
int main()
{
int array[10];
return 0;
}
I am learning, and at the moment it feels that there is not much differnce between
declaring a variable (array, whatever) -with Global scope,
when compared to a
dynamically allocated variable (array, whatever) -AND never calling free() on it AND allowing it to be 'destoryed' when the program ends'
What are the consequences of either option?
EDIT
Thank you for your responses.
Global scope should have been 'local scope' -local to main()
When you declare an array like int arr[10] in a function, the space for the array is allocated on the stack. The memory will be freed when your function exits.
When you declare an array or any other data structure using malloc() or realloc(), you allocated the space on the heap and the memory will only be freed afer the program exits. So when the program is running, you are responsible for freeing it using free() after you no longer want to use it. If you don't free it and make your array pointer point to something else, you will create a memory leak. However, your computer will always be able to retrieve all the program's used memory after the program ends because of virtual memory.
As kaylum said in comment below your question, the array in your second example does not have global scope. Its scope is limited to main(), and it is inaccessible in other scopes unless main() explicitly makes it available (e.g. passes it by argument to another function).
Dynamic memory allocation means that the programmer explicitly allocates memory when needed, and explicitly releases it when no longer needed. Because of that, the amount of memory allocated can be determined at run time (e.g. calculated from user input). Also, if the programmer forgets to release the memory, or reallocates it inappropriately, memory can be leaked (still allocated by the program, but not accessible by the program). For example;
/* within a function */
char *p = malloc(100);
p = malloc(200);
free(p);
leaks 100 bytes, every time this code is executed, because the result of the first malloc() call is never released, and it is then inaccessible to the program because its value is not stored anywhere.
Your second example is actually an array of automatic storage duration. As far as your program is concerned, it only exists until the end of the scope in which it is created. In your case, as main() returns, the array will cease to exist.
An example of an array with global scope is
int array[10];
void f() {array[0] = 42;}
int main()
{
array[0] = 10;
f();
/* array[0] will be 42 here */
}
The difference is that this array exists and is accessible to every function that has visibility of the declaration, within the same compilation unit.
One other important difference is that global arrays are (usually) zero initialised - a global array of int will have all elements zero. A dynamically allocated array will not have elements initialised (unless created with calloc(), which does initialise to zero). Similarly, an automatic array will not have elements initialised. It is undefined behaviour to access the value of something (including an array element) that is uninitialised.
So
#include <stdio.h>
int array[10];
int main()
{
int *array2;
int array3[10];
array2 = malloc(10*sizeof(*array2));
printf("%d\n", array[0]); /* okay - will print 0 */
printf("%d\n", array2[0]); /* undefined behaviour. array2[0] is uninitialised */
printf("%d\n", array3[0]); /* undefined behaviour. array3[0] uninitialised */
return 0;
}
Obviously the way to avoid undefined behaviour is to initialise array elements to something valid before trying to access their value (e.g. printing them out, in the example above).
i know that heap is used in case of dynamic memory allocation otherwise stack is used.
i have tried Difference between static memory allocation and dynamic memory allocation
i know the difference but confusion is about their lifetimes.
First of all, stacks and heaps are implementation details (the words "stack" and "heap" do not appear anywhere in the C language standard). Instead, the standard talks about storage durations for objects (Section 6.2.4).
As of C2011, there are four storage durations: static, automatic, thread, and allocated.
Objects with static storage duration have lifetimes1 that extend over the lifetime of the program. That is, memory is set aside for them when the program is loaded, and that memory is released when the program exits. Objects declared at file scope (outside of any function) or with the static keyword have static storage duration. Storage for static objects is usually allocated from within the binary image itself (for ELF, this would include the .data, .rodata, and .bss sections); that is, something other than a stack or heap.
Objects with automatic storage duration have lifetimes that extend from the entry of the block in which they're created until the block exits2. If the block is entered recursively, a new object is created. Objects declared within a block without the static keyword have automatic storage duration. Objects with automatic storage duration are usually allocated from a runtime hardware stack, although not all architectures have a stack.
Objects with thread storage duration have lifetimes that extend over the execution of the thread for which they were created. Objects declared with the _Thread_local keyword have thread storage duration. I think thread-local objects are allocated in the same way as auto variables, but that may be wrong; I've never used C2011 native threading, so I can't say for sure.
Objects with allocated storage duration have lifetimes that extend from the time they are allocated with malloc, calloc, or realloc until they are explicitly deallocated with a call to free. Objects with allocated storage duration are usually allocated from the heap (although not all architectures will have a heap as such). Where things get confusing is distinguishing the allocated object from the object that points to it. Given the following code:
int *foo( void )
{
int *bar = malloc( sizeof *bar * 10 );
// do stuff with bar
return bar;
}
void bletch( void )
{
int *blurga = foo();
// do stuff with blurga
free( blurga );
}
We've allocated three objects. In the function foo, we allocate a pointer object (referred to by the variable bar) with automatic storage duration; its lifetime is the lifetime of the function foo. In the function bletch, we allocate another pointer object (referred to by the variable blurga) with automatic storage duration; its lifetime extends over the lifetime of the function bletch.
The third object is a buffer large enough to hold 10 int objects. Its lifetime extends from the malloc call in foo to the free call in bletch; its lifetime is not tied to the lifetime of any function or block.
1. The lifetime of an object is the time within a program's execution that storage is guaranteed to be reserved for that object. Note that the lifetime of an object is distinct from the scope of the identifier that refers to that object. Even though memory for the object may be allocated at block entry, the scope of the identifier that refers to it may be more limited.
Assume the following code:void foo()
{
printf( "entered foo\n" );
int i = 0;
while ( i < 10 )
printf( "%d\n", i++ );
}
The scope of the variable i extends from the end of its declaration until the end of the block; however, the lifetime of the integer object i refers to extends from block entry until block exit.
2. In practice, most compilers will set aside storage for all block-scope variables at function entry, even though some may be local to a block within the function. However, it's best to assume that the lifetime of an auto object only extends to the block in which it is contained.
Stack variables have local scope, meaning they are only valid to de-reference within the pair of {} where they were declared. While a dynamically allocated variable is valid until the point where your program calls free().
A more correct name would be local variables, since local variables may also end up allocated in CPU registers and not always on the stack. Formally, they are called variables with automatic storage duration in the C standard, meaning that the compiler automatically decides which is the best place to allocate them at.
After ignoring C for my entire CS career I have decided to give it a look!
When initialising variables, we can have :
int b = 0;
This initialises b, allocates memory for it, and we can later update it with
b = 2;
if needs be.
So, and forgive me for this ridiculously "noob" question but why do we need calls like :
double *b = (double *) calloc(n, sizeof(double));
when initialising the variable would allocate the space for it already?
Why can we not just do
double b = 0;
b* = b.addressOf(b) //or some similar construct.
What is the use of this?
I have tried Googling this to no avail so please forgive me - ufortunately * in Google is a wildcard and so relevant results are hard to find.
Variables declared in the current context end their lifetime at the end of the context.
Allocating memory gives you space to store longer-lived variables.
For example,
double *foo() {
double d;
return &d;
}
void bar() {
double *d = foo();
*d = 0.0;
}
will try to access a variable that no longer exists, because its lifetime is the foo function.
C and C++ do not keep track of objects. A pointer only points to the object, but does not extend object lifetime, so it is entirely possible for a pointer to be invalid even if it is not NULL.
However, this is valid:
double *foo() {
return (double *)malloc(sizeof(double));
}
void bar() {
double *d = foo();
*d = 0.0;
}
This will allocate memory for a double, and return the pointer to the memory, which remains valid until explicitly returned to the pool using the free function. Not returning it to the pool will create a memory leak.
Unless I'm totally mistaken, in C, calloc or malloc are the only possibilities to implement dynamic data structures.
When it comes about variable allocation you can do it like:
statically on the stack, simply: int a = 10. These variables are defined on the stack most possibly together with some of the code using them (this is why it can be dangerous to write in an array declared on the stack without proper checking the boudadries. You might overwrite code). The variables also have a scope: function scope, global scope, and other scopes (such as the if-branch of an if-else). They are fast to use, however they are more or less ... static, and they have the big advantage that you don't need to clean them. They are automatically cleaned by the application. However they have a great disadvantage. Stack space is more limited than heap space. So you can use only modest sized variables (Don't take it literally, instead do some research what is allowed by your OS . 64KB is not enough to everyone :) ).
Dynamically on the heap, using either calloc() or some other memory allocation function. These variables are declared in an area known as the heap, or dynamic memory. These variables will stay there either until the application using them exits (in this case the (modern) OS usually reclaims the memory to itself), or they are freed using free(). You always should free the memory to avoid memory leaks. Dynamic memory has the advantage that (on a modern OS) the addressable memory is much bigger than the size allocated to stack space so you can have more, bigger, greater structures and arrays.
Scope is the region or section of the code where a variable can be accessed. There can be
File Scope
Function Scope
Block Scope
Program Scope
Prototype Scope
Example
#include<stdio.h>
void function1()
{
printf("In function1\n");
}
static void function2()
{
printf("In function2\n");
{
int i = 100;
Label1:
printf("The value of i =%d\n",i);
i++;
if(i<105)
goto Label1;
}
}
void function3(int x, int y);
int main(void)
{
function1();
function2();
return 0;
}
In the example,
‘function1()’ has ‘Program Scope’.
‘function2()’ has ‘File Scope’.
‘Label1’ has ‘Function Scope’. (Label names must be unique within the functions. ‘Label’ is the only identifier that has function scope.
Variable ‘i’ has ‘Block Scope’.
Variable ‘x’ and ‘y’ has ‘Prototype Scope’. There cannot be two variables with the name ‘x’ or ‘y’ in the function parameter list.
The variable i in the above example have the block scope. If the control goes out of scope (life ends), then the variable is gone. You can not access the variable.
So C provides dynamic memory constructs to access the memory in these kind of scenarios.
For example:
int* function(void)
{
int *ptr = malloc(sizeof(int));
*ptr = 5;
return ptr;
}
int main(void)
{
printf("%d", function());
return 0;
}
the printf would still print the value even the variable ptr is out of scope but the memory pointed by ptr still exists (has life).
Also read https://stackoverflow.com/a/18479996/1814023