This question already has answers here:
What's the difference between a VLA and dynamic memory allocation via malloc?
(4 answers)
Closed 6 years ago.
There are two ways to allocate memory to an array, of which the size is unknown at the beginning. The most common way is using malloc like this
int * array;
... // when we know the size
array = malloc(size*sizeof(int));
But it's valid too in C99 to define the array after we know the size.
... // when we know the size
int array[size];
Are they absolutely the same?
No they're not absolutely the same. While both let you store the same number and type of objects, keep in mind that:
You can free() a malloced array, but you can't free() a variable length array (although it goes out of scope and ceases to exist once the enclosing block is left). In technical jargon, they have different storage duration: allocated for malloc versus automatic for variable length arrays.
Although C has no concept of a stack, many implementation allocate a variable length array from the stack, while malloc allocates from the heap. This is an issue on stack-limited systems, e.g. many embedded operating systems, where the stack size is on the order of kB, while the heap is much larger.
It is also easier to test for a failed allocation with malloc than with a variable length array.
malloced memory can be changed in size with realloc(), while VLAs can't (more precisely only by executing the block again with a different array dimension--which loses the previous contents).
A hosted C89 implementation only supports malloc().
A hosted C11 implementation may not support variable length arrays (it then must define __STDC_NO_VLA__ as the integer 1 according to C11 6.10.8.3).
Everything else I have missed :-)
Related
This question already has answers here:
What's the difference between a VLA and dynamic memory allocation via malloc?
(4 answers)
Closed 6 years ago.
In the following code I'm providing size of array at run time.
#include <stdio.h>
int main()
{
int i;
scanf("%d",&i);
int a[i];
}
Please tell me the difference between the code above and code using malloc().
I know that array store is on the stack and dynamic memory (malloc, calloc etc) is on the heap.
So is my code functioning similar to malloc? If not, please explain.
Apart from your code uses VLA which:
did not exist before C99
were introduced as a new feature in C99
are now an optional feature since C11
The difference is that automatic arrays (VLA or static size ones) are automatically release when they go out of scope, so you cannot return them from a function, while dynamically allocated ones persist until they are explicitely freed - which shall happen before you lose a pointer to them if you do not want a memory leak.
The Above statement works in C99, but there are limitations of using this approach:
int a[i] is variable length array not the memory dynamically
allocated, hence it will store on STACK instead of HEAP "which it does
in case of malloc" hence there will be situation when somebody entered
MAX_INT and your STACK memory limit is very less(Ex : Embedded
Systems) then Stack Corruption might occur.
This question already has answers here:
When is malloc necessary in C?
(8 answers)
Closed 8 years ago.
It is often said to use malloc when size is known at run time we could also write
int x;
scanf("%d",&x);
char arr[x];
so why use malloc when we can declare array on the fly.
Writing char arr[x]; will allocate the memory on the stack.
The size of the stack is typically limited to around 1MB. You'll get runtime errors if you exceed this pre-defined amount. Some compilers will allow you to change the stack size, but you'll still hit a limit eventually of many orders of magnitude than you can get with malloc.
VLA [Variable length array] is a concept present in C99 onwards.
malloc() originates much before that.
Also, malloc() and family allocates memory from heap. It does not use the comparatively limited stack space.
OTOH, gcc allocates space for VLAs in the stack itself.
How compiler determine the size of below array at compile time?
int n;
scanf("%d",&n);
int a[n];
How it is different from dynamic allocation(other than memory is allocated in heap for dynamic array).
If possible please, explain this in terms of activation stack memory image how this array is allocated memory.
The array's size isn't determined at compile time; it's determined at run time. At the time that the array is allocated, n has a known value. In typical implementations where automatic variables are allocated on the program stack, the stack pointer will be adjusted to make room for that many ints. It becomes parts of the stack frame and will be automatically reclaimed when it goes out of scope.
This code was not valid in C90; C90 required that all variables be declared at the beginning of the block, so mixing declarations and code like this was not permitted. Variable-length arrays and mixed code and declarations were introduced in C99.
In C the proper name for the allocation type is automatic. In computing jargon the term stack is sometimes used synonymously.
The storage of a is valid from the point of definition int a[n]; up until the end of the enclosing scope (i.e. the end of the current function, or earlier).
It is just the same as int a[50]; , except that a different number of ints than 50 may be allocated.
A drawback of using automatic arrays (with or without runtime sizes) is that there is no portable way to protect against stack overflow. (Actually, stack overflow from automatic variables is something the C standard does not address at all, but it is a real problem in practice).
If you were to use dynamic allocation (i.e. malloc and friends) then it will let you know if there is insufficient memory by returning NULL, whereas stack overflows are nasty.
This is also a valid code to declare dynamic arrays.
malloc needs pointers, this doesn't. Is this a better method?
printf("enter the size of array")
scanf("%d",&x)
const int size
size = x
int array[size]
It is hard to say if one is better than the other, a better question would be what are the advantages of each, you need to decided based on your requirements but using malloc and using variable length arrays(VLA) are not the same.
There are some major differences.1) A VLA will usually be allocated on the stack although that is an implementation decision, the standard just says there are automatic. The stack is more limited than the the heap which is where a malloc'ed array will go and so you can easily overflow your stack. 2) You need to free a malloc'ed array a VLA is an automatic variable and will not exist outside of the scope it is declared in. 3) VLA is part of the C99 standard and so code using VLA will not be portable.
This question already has answers here:
Array of zero length
(5 answers)
Closed 8 years ago.
In reference to GCC's Zero Length Array explanation:
This is particularly useful in the case when a struct is a header for a variable-length object. This is exactly my case. Furthermore, I am concerned with the alignment of my structs in the heap.
In this case, I still really do not understand what's useful about zero length arrays. How are they related to this particular situation?
EDIT:
Is it that I can put as much "data" as I want in there?
Basically it allows you to have a structure with a variable length array at the end:
struct X {
int first;
int rest[0];
};
An array size of 0 is not actually valid (although it is allowed as a gcc extension). Having an unspecified size is the correct way.
Since C doesn't really care that you are accessing elements beyond the end of the array, you just start with an undefined array size, and then allocate enough memory to handle however many elements you actually want:
struct X *xp = (struct X *)malloc(sizeof(struct X)+10*sizeof(int));
xp->rest[9] = 0;
The memory returned from malloc() that you will assign to a pointer to the struct with the zero-length array member will be aligned memory ... that's required by the C99 specification. So there is no issue overlaying a struct with a zero-length array over memory allocated from the heap via malloc().
Where you would run into trouble would be attempting to overlay your struct over some raw buffer in memory that came from a packed or non-traditionally aligned data-source, such as a file-header, memory-mapped hardware interface, etc. In those cases, using a zero-length array to handle the variable-length data can be a bad idea since the data may not be aligned according to the default alignment parameters of the platform, and thus offsetting into the array will not yield the correct results.