C Dynamic Allocation w/Pointers [duplicate] - c

I was curious with this:
What is the diference between:
const int MAX_BUF = 1000;
char* Buffer = malloc(MAX_BUF);
and:
char Buffer[MAX_BUF];

Case 1: In
char Buffer[MAX_BUF];
Buffer is an array of size MAX_BUF. The allocation technique is called VLA.
Case 2: In
const int MAX_BUF = 1000;
char* Buffer = malloc(MAX_BUF);
Buffer is a pointer which is allocated a memory of size MAX_BUF which is 1000.
and, an array is not the same as a pointer, and C-FAQ has a Very Good collection detailing the reasons.
The major difference, in terms of usability and behaviour are:
(1) is on stack, usually Note, while (2) is on heap, always.
(1) has fixed size once allocated, (2) can be resized.
(1) is allocated when the enclosing function is called and has the block scope OTOH, (2) is allocated memory dynamically, at runtime and the returned memory has a lifetime which extends from the allocation until the deallocation.
(1) allocated memory need not be managed by programmer, while in (2) all malloc()d memory should be free()d. [Courtesy: Giorgi]
Note: Wiki
For example, the GNU C Compiler allocates memory for VLAs on the stack.

I will add a bit info in terms of memory management, in addition to what others said.
1) The main difference is here:
const int MAX_BUF = 1000;
char* Buffer = malloc(MAX_BUF);
You need to manage the allocated memory manually, e.g., free Buffer when you are done using it. Forgetting to free it (or freeing it twice) may lead to trouble.
2) With the second case:
char Buffer[MAX_BUF];
You don't need to free anything. It will get destroyed automatically. Hence you avoid the task of handling the memory - which is good.
You should try to evaluate always which approach you need.
Some points.
Since second is allocated on stack, the first approach is taken also when large array needs to be created - since more memory is usually available on the heap.
Also if you create array using second approach for example in the method, the life time of the object will be that method - you will not be able to use that array outside that method. Whereas with dynamic allocation that is not the case.

char* Buffer = malloc(MAX_BUF);
creates a char pointer Buffer, dynamically allocates MAX_BUF bytes of memory via the malloc and makes Buffer point to the start of the allocated space. This memory is allocated on the heap.
char Buffer[MAX_BUF];
creates an array Buffer of size MAX_BUF which can hold a maximum of MAX_BUF characters. Note that you are creating a Variable Length Array (a feature introduced in C99) since MAX_BUF is a variable. This array may be created on the stack.

The most notable difference is scope. The VLA array will only be valid inside the scope where it is declared, while a dynamic array will be available everywhere in the program until you call free().
In practice, VLAs may be faster than dynamic memory, in case the compiler use stack allocation for the VLA. It is however not specified by the C standard where a VLA is allocated.
(A compiler could in theory allocate a VLA on the heap, but then the compiler would also be responsible for the clean-up. I don't think any such solutions exist. Every compiler I've used always declare VLAs on the stack.)
This means that VLAs are unsuitable to hold large amounts of data: you would risk stack overflow. This is not a concern when you are using dynamic memory however.
VLAs don't have the same portability as dynamic arrays, since awfully old compilers don't support VLAs. In theory, new C11 compilers don't have to suport VLAs either, though at this point I know of no compiler has been stupid enough to drop that support.
Comparison/summary:
VLAs should be used when there are small amounts of local data, because they have fast allocation time and automatic clean-up.
Dynamic arrays should be used when there are large amounts of data, to prevent stack overflow.
Dynamic arrays should be used when the data needs to persist after the execution of a function and be available elsewhere in the program.
Dynamic arrays should be used when you have exceptional and/or irrational portability requirements.

Related

memset and static array declaration vs malloc [duplicate]

I was curious with this:
What is the diference between:
const int MAX_BUF = 1000;
char* Buffer = malloc(MAX_BUF);
and:
char Buffer[MAX_BUF];
Case 1: In
char Buffer[MAX_BUF];
Buffer is an array of size MAX_BUF. The allocation technique is called VLA.
Case 2: In
const int MAX_BUF = 1000;
char* Buffer = malloc(MAX_BUF);
Buffer is a pointer which is allocated a memory of size MAX_BUF which is 1000.
and, an array is not the same as a pointer, and C-FAQ has a Very Good collection detailing the reasons.
The major difference, in terms of usability and behaviour are:
(1) is on stack, usually Note, while (2) is on heap, always.
(1) has fixed size once allocated, (2) can be resized.
(1) is allocated when the enclosing function is called and has the block scope OTOH, (2) is allocated memory dynamically, at runtime and the returned memory has a lifetime which extends from the allocation until the deallocation.
(1) allocated memory need not be managed by programmer, while in (2) all malloc()d memory should be free()d. [Courtesy: Giorgi]
Note: Wiki
For example, the GNU C Compiler allocates memory for VLAs on the stack.
I will add a bit info in terms of memory management, in addition to what others said.
1) The main difference is here:
const int MAX_BUF = 1000;
char* Buffer = malloc(MAX_BUF);
You need to manage the allocated memory manually, e.g., free Buffer when you are done using it. Forgetting to free it (or freeing it twice) may lead to trouble.
2) With the second case:
char Buffer[MAX_BUF];
You don't need to free anything. It will get destroyed automatically. Hence you avoid the task of handling the memory - which is good.
You should try to evaluate always which approach you need.
Some points.
Since second is allocated on stack, the first approach is taken also when large array needs to be created - since more memory is usually available on the heap.
Also if you create array using second approach for example in the method, the life time of the object will be that method - you will not be able to use that array outside that method. Whereas with dynamic allocation that is not the case.
char* Buffer = malloc(MAX_BUF);
creates a char pointer Buffer, dynamically allocates MAX_BUF bytes of memory via the malloc and makes Buffer point to the start of the allocated space. This memory is allocated on the heap.
char Buffer[MAX_BUF];
creates an array Buffer of size MAX_BUF which can hold a maximum of MAX_BUF characters. Note that you are creating a Variable Length Array (a feature introduced in C99) since MAX_BUF is a variable. This array may be created on the stack.
The most notable difference is scope. The VLA array will only be valid inside the scope where it is declared, while a dynamic array will be available everywhere in the program until you call free().
In practice, VLAs may be faster than dynamic memory, in case the compiler use stack allocation for the VLA. It is however not specified by the C standard where a VLA is allocated.
(A compiler could in theory allocate a VLA on the heap, but then the compiler would also be responsible for the clean-up. I don't think any such solutions exist. Every compiler I've used always declare VLAs on the stack.)
This means that VLAs are unsuitable to hold large amounts of data: you would risk stack overflow. This is not a concern when you are using dynamic memory however.
VLAs don't have the same portability as dynamic arrays, since awfully old compilers don't support VLAs. In theory, new C11 compilers don't have to suport VLAs either, though at this point I know of no compiler has been stupid enough to drop that support.
Comparison/summary:
VLAs should be used when there are small amounts of local data, because they have fast allocation time and automatic clean-up.
Dynamic arrays should be used when there are large amounts of data, to prevent stack overflow.
Dynamic arrays should be used when the data needs to persist after the execution of a function and be available elsewhere in the program.
Dynamic arrays should be used when you have exceptional and/or irrational portability requirements.

C: How do I initialize a global array when size is not known until runtime?

I am writing some code in C (not C99) and I think I have a need for several global arrays. I am taking in data from several text files I don't yet know the size of, and I need to store these values and have them available in several different methods. I already have written code for reading the text files into an array, but if an array isn't the best choice I am sure I could rewrite it.
If you had encountered this situation, what would you do? I don't necessarily need code examples, just ideas.
Use dynamic allocation:
int* pData;
char* pData2;
int main() {
...
pData = malloc(count * sizeof *pData); // uninitialized
pData2 = calloc(count, sizeof *pData2); // zero-initialized
/* work on your arrays */
free(pData);
free(pData2);
...
}
First of all, try to make sense of the requirement. You cannot possibly initialize a memory of "unknown" size, you can only have it initialized once you have a certain amount of memory (in terms of bytes). So, the first thing is to get the memory allocated.
This is the scenario to use memory allocator functions, malloc() and family, which allows you to allocate memory of a given size at run-time. Define a pointer, then, at run-time, get the memory size and use the allocator functions to allocate the memory of required size.
That said,
calloc() initializes the returned memory to 0.
realloc() is used to re-size the memory at run-time.
Also, while using dynamic memory allocation, you should be careful enought to clean up the allocated memory using free() when you're done using the memory to avoid memory leaks.

What's the difference between a VLA and dynamic memory allocation via malloc?

I was curious with this:
What is the diference between:
const int MAX_BUF = 1000;
char* Buffer = malloc(MAX_BUF);
and:
char Buffer[MAX_BUF];
Case 1: In
char Buffer[MAX_BUF];
Buffer is an array of size MAX_BUF. The allocation technique is called VLA.
Case 2: In
const int MAX_BUF = 1000;
char* Buffer = malloc(MAX_BUF);
Buffer is a pointer which is allocated a memory of size MAX_BUF which is 1000.
and, an array is not the same as a pointer, and C-FAQ has a Very Good collection detailing the reasons.
The major difference, in terms of usability and behaviour are:
(1) is on stack, usually Note, while (2) is on heap, always.
(1) has fixed size once allocated, (2) can be resized.
(1) is allocated when the enclosing function is called and has the block scope OTOH, (2) is allocated memory dynamically, at runtime and the returned memory has a lifetime which extends from the allocation until the deallocation.
(1) allocated memory need not be managed by programmer, while in (2) all malloc()d memory should be free()d. [Courtesy: Giorgi]
Note: Wiki
For example, the GNU C Compiler allocates memory for VLAs on the stack.
I will add a bit info in terms of memory management, in addition to what others said.
1) The main difference is here:
const int MAX_BUF = 1000;
char* Buffer = malloc(MAX_BUF);
You need to manage the allocated memory manually, e.g., free Buffer when you are done using it. Forgetting to free it (or freeing it twice) may lead to trouble.
2) With the second case:
char Buffer[MAX_BUF];
You don't need to free anything. It will get destroyed automatically. Hence you avoid the task of handling the memory - which is good.
You should try to evaluate always which approach you need.
Some points.
Since second is allocated on stack, the first approach is taken also when large array needs to be created - since more memory is usually available on the heap.
Also if you create array using second approach for example in the method, the life time of the object will be that method - you will not be able to use that array outside that method. Whereas with dynamic allocation that is not the case.
char* Buffer = malloc(MAX_BUF);
creates a char pointer Buffer, dynamically allocates MAX_BUF bytes of memory via the malloc and makes Buffer point to the start of the allocated space. This memory is allocated on the heap.
char Buffer[MAX_BUF];
creates an array Buffer of size MAX_BUF which can hold a maximum of MAX_BUF characters. Note that you are creating a Variable Length Array (a feature introduced in C99) since MAX_BUF is a variable. This array may be created on the stack.
The most notable difference is scope. The VLA array will only be valid inside the scope where it is declared, while a dynamic array will be available everywhere in the program until you call free().
In practice, VLAs may be faster than dynamic memory, in case the compiler use stack allocation for the VLA. It is however not specified by the C standard where a VLA is allocated.
(A compiler could in theory allocate a VLA on the heap, but then the compiler would also be responsible for the clean-up. I don't think any such solutions exist. Every compiler I've used always declare VLAs on the stack.)
This means that VLAs are unsuitable to hold large amounts of data: you would risk stack overflow. This is not a concern when you are using dynamic memory however.
VLAs don't have the same portability as dynamic arrays, since awfully old compilers don't support VLAs. In theory, new C11 compilers don't have to suport VLAs either, though at this point I know of no compiler has been stupid enough to drop that support.
Comparison/summary:
VLAs should be used when there are small amounts of local data, because they have fast allocation time and automatic clean-up.
Dynamic arrays should be used when there are large amounts of data, to prevent stack overflow.
Dynamic arrays should be used when the data needs to persist after the execution of a function and be available elsewhere in the program.
Dynamic arrays should be used when you have exceptional and/or irrational portability requirements.

how is dynamic memory allocation better than array?

int numbers*;
numbers = malloc ( sizeof(int) * 10 );
I want to know how is this dynamic memory allocation, if I can store just 10 int items to the memory block ? I could just use the array and store elemets dynamically using index. Why is the above approach better ?
I am new to C, and this is my 2nd day and I may sound stupid, so please bear with me.
In this case you could replace 10 with a variable that is assigned at run time. That way you can decide how much memory space you need. But with arrays, you have to specify an integer constant during declaration. So you cannot decide whether the user would actually need as many locations as was declared, or even worse , it might not be enough.
With a dynamic allocation like this, you could assign a larger memory location and copy the contents of the first location to the new one to give the impression that the array has grown as needed.
This helps to ensure optimum memory utilization.
The main reason why malloc() is useful is not because the size of the array can be determined at runtime - modern versions of C allow that with normal arrays too. There are two reasons:
Objects allocated with malloc() have flexible lifetimes;
That is, you get runtime control over when to create the object, and when to destroy it. The array allocated with malloc() exists from the time of the malloc() call until the corresponding free() call; in contrast, declared arrays either exist until the function they're declared in exits, or until the program finishes.
malloc() reports failure, allowing the program to handle it in a graceful way.
On a failure to allocate the requested memory, malloc() can return NULL, which allows your program to detect and handle the condition. There is no such mechanism for declared arrays - on a failure to allocate sufficient space, either the program crashes at runtime, or fails to load altogether.
There is a difference with where the memory is allocated. Using the array syntax, the memory is allocated on the stack (assuming you are in a function), while malloc'ed arrays/bytes are allocated on the heap.
/* Allocates 4*1000 bytes on the stack (which might be a bit much depending on your system) */
int a[1000];
/* Allocates 4*1000 bytes on the heap */
int *b = malloc(1000 * sizeof(int))
Stack allocations are fast - and often preferred when:
"Small" amount of memory is required
Pointer to the array is not to be returned from the function
Heap allocations are slower, but has the advantages:
Available heap memory is (normally) >> than available stack memory
You can freely pass the pointer to the allocated bytes around, e.g. returning it from a function -- just remember to free it at some point.
A third option is to use statically initialized arrays if you have some common task, that always requires an array of some max size. Given you can spare the memory statically consumed by the array, you avoid the hit for heap memory allocation, gain the flexibility to pass the pointer around, and avoid having to keep track of ownership of the pointer to ensure the memory is freed.
Edit: If you are using C99 (default with the gnu c compiler i think?), you can do variable-length stack arrays like
int a = 4;
int b[a*a];
In the example you gave
int *numbers;
numbers = malloc ( sizeof(int) * 10 );
there are no explicit benefits. Though, imagine 10 is a value that changes at runtime (e.g. user input), and that you need to return this array from a function. E.g.
int *aFunction(size_t howMany, ...)
{
int *r = malloc(sizeof(int)*howMany);
// do something, fill the array...
return r;
}
The malloc takes room from the heap, while something like
int *aFunction(size_t howMany, ...)
{
int r[howMany];
// do something, fill the array...
// you can't return r unless you make it static, but this is in general
// not good
return somethingElse;
}
would consume the stack that is not so big as the whole heap available.
More complex example exists. E.g. if you have to build a binary tree that grows according to some computation done at runtime, you basically have no other choices but to use dynamic memory allocation.
Array size is defined at compilation time whereas dynamic allocation is done at run time.
Thus, in your case, you can use your pointer as an array : numbers[5] is valid.
If you don't know the size of your array when writing the program, using runtime allocation is not a choice. Otherwise, you're free to use an array, it might be simpler (less risk to forget to free memory for example)
Example:
to store a 3-D position, you might want to use an array as it's alwaays 3 coordinates
to create a sieve to calculate prime numbers, you might want to use a parameter to give the max value and thus use dynamic allocation to create the memory area
Array is used to allocate memory statically and in one go.
To allocate memory dynamically malloc is required.
e.g. int numbers[10];
This will allocate memory statically and it will be contiguous memory.
If you are not aware of the count of the numbers then use variable like count.
int count;
int *numbers;
scanf("%d", count);
numbers = malloc ( sizeof(int) * count );
This is not possible in case of arrays.
Dynamic does not refer to the access. Dynamic is the size of malloc. If you just use a constant number, e.g. like 10 in your example, it is nothing better than an array. The advantage is when you dont know in advance how big it must be, e.g. because the user can enter at runtime the size. Then you can allocate with a variable, e.g. like malloc(sizeof(int) * userEnteredNumber). This is not possible with array, as you have to know there at compile time the (maximum) size.

Stack variables vs. Heap variables

Am I correct in thinking that:
char *buff[500];
... creates a stack variable, and:
char *buff = (char *)malloc(500);
... creates a heap variable?
If that's correct, when and why would you use heap variables over stack variables and vice versa. I understand the stack is faster is there anything else.
One last question, is the main function a stack frame on the stack?
Yes, first one creates an array of char pointers in the stack, about 500*4 bytes and second one allocates 500 chars in the heap and points a stack char ptr to them.
Allocating in the stack is easy and fast, but stack is limited, heap is slower but much bigger. Apart from that, stack allocated values are "deleted" once you leave the scope, so it is very good for small local values like primitive variables.
If you allocate too much in the stack you might run out of stack and die, main as all the functions you execute has a stack frame in the stack and all the local variables to the function are stored there, so going too deep into function calling might get you into a stackoverflow as well.
In general is a good rule of thumb to allocate anything that you use often and is bigger than a hundred bytes in the heap, and small variables and pointers in the stack.
Seeing that you wrote
char *buff = (char *)malloc(500);
you probably meant
char buff[500]; instead of
char* buff[500];
in your first example (so you have a char-array, not an array of pointers to chars)
Yes, "allocation" on the stack is faster because you just increase a pointer stored in the ESP register.
You need heap-variables if you want:
1) more memory than fits in the stack (generally much earlier)
2) pass memory that was allocated by a called function to the calling function.
Your buffs are not equivalent.
The first one (char *buff[500]) is an array of 500 pointers; the 2nd one (char *buff = (char *)malloc(500)) is a pointer.
The pointer (on the stack) points to 500 bytes of memory (if the malloc call succeeded) on the heap.
The array of pointers is on the stack. Its pointers are not initialized.
Unless using C99, using the stack the size of your array must be known at compile-time. That means you cannot do:
int size = 3; // somewhere, possibly from user input
char *buff[size];
But using "the heap" (dynamic allocation), you can provide any dimensions you like. That's because the memory allocation is performed at run-time, rather than hardcoded into the executable.
The C standard contains neither the words heap nor stack. What we have here instead are two storage durations (of 4 in total): automatic and allocated:
char buff[500]; // note the missing * to match the malloc example
within a function declares the object buff as an array of char and having automatic storage duration. The object will cease to be when the block where the object was declared, is exited.
char *buff = malloc(500); // no cast necessary; this is C
will declare buff as a pointer to char. malloc will reserve 500 continuous bytes and return a pointer to it. The returned 500-byte object will exist until it is explicitly freed with a call to free. The object is said to have allocated storage duration.
That's all the C standard says. It doesn't specify that the char buff[500] needs to be allocated from a "stack", or that there needs to be a stack. It doesn't specify that the malloc needs to use some "heap". On the contrary, a compiler might internally implement the char buff[500] like
{
char *buff = malloc(500);
free(buff);
}
Or it can deduce that the allocated memory is not used, or that it is only used once, and use a stack-based allocation instead of actually calling malloc.
In practice, most current compilers and environments will use a memory layout called stack for automatic variables, and the objects with allocated storage duration are said to come from "heap" which is a metaphor for the unorganized mess that it is compared to the orderly stack, but it is not something that has to be so.
Heap variables can be created dynamically, ie you can ask a size to your user and malloc a new variable with this size.
The size of a stack variable must be known at compile time.
Like you said, stack variable are faster allocated and accessed. So i'll recommend using them every time you know the size at compile time. Otherwise you don't have the choice, you must use malloc()
This is indeed a variable allocated on the stack:
char buff[500]; // You had a typo here?
and this is on the heap:
char *buff = (char *)malloc(500);
Why would you use one vs the other?
In char *buff[500], the 500 needs to be a compile-time constant. You can't use it if 500 is computed at runtime.
On the other hand, stack allocations are instantaneous while heap allocations take time (thus they incur a runtime performance cost).
Space on the stack is limited by the thread's stack size (typically 1MB before you get a stack overflow), while there's much more available on the heap.
If you allocate an array on the stack big enough to take up more than 2 pages of virtual memory as managed by the OS, and access the end of the array before doing anything else, there's the possibility of getting a protection fault (this depends on the OS)
Finally: every function called has a frame on the stack. The main function is no different. It isn't even any more special than the other functions in your program, since when your program starts running the first code that runs is inside the C runtime environment. After the runtime is ready to begin execution of your own code, it calls main just as you would call any other function.
Those two aren't equivalent. The first is an array of size 500 (on the stack) with pointers to characters. The second is a pointer to a memory chunk of 500 which can be used with the indexing operator.
char buff[500];
char *buff = (char *)malloc(sizeof(char)*500);
Stack variables should be preferred because they require no deallocation. Heap variables allow passing of data between scopes as well as dynamic allocation.

Resources