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.
Related
This question already has answers here:
Undefined, unspecified and implementation-defined behavior
(9 answers)
Is it undefined behaviour to access an array beyond its end, if that area is allocated? [duplicate]
(3 answers)
Array index out of bound behavior
(10 answers)
Getting no segmentation fault when exceeding the size that was allocated for a char * [duplicate]
(1 answer)
Closed 5 years ago.
The title may not be accurate. Please excuse me for being a completely new programmer in c. But it is a genuine question which I believe will benefit others who were as confused by memory and pointers as I was when learning my first low-level programming language, that is C.
Here is what I know in regard to this:
Pointers are variables that store memory addresses.
You can allocate a place in memory using the malloc function from the stdlib.h header file, which returns a pointer to the memory allocated.
The malloc function takes the size of what you want to store in bytes as a parameter
Which leads me to ask: What if you store something of a bigger size in the place in memory allocated by the malloc function, where you passed a smaller size as the parameter for the malloc function?
Naturally, the first thing I did was obviously try it. I take input using scanf, which then stores the input in the allocated memory. Here is the code:
#include <stdio.h>
#include <stdlib.h>
int main(){
char *string_pointer;
string_pointer = malloc(sizeof(char)*24);
if (string_pointer == NULL){
puts("Memory allocation failed:(");
return 1;
}else{}
scanf("%s",string_pointer);
printf("%s",string_pointer);
return 0;
}
You can see that I allocated a place in memory, passing in sizeof(char)*24 as the parameter. Then I stored the pointer of this memory in the string_pointer variable.
Now if I feed scanf with a string that is more than 24 characters (bigger size than the allocated memory), it still works, When I print out the contents of the memory, I get the whole string as it is, even though that means that it stored a string of a bigger size than what it can hold. This shows that I have an obvious misconception of how memory allocation works. It might be because that malloc doesn't allocate a memory that can only hold the size that I passed to malloc, and the whole size parameter thing is for a totally different purpose.
I am completely confused? How come I just stored a string in a memory allocated that can hold less than the size of the string?
This question already has answers here:
C array size given by variable
(2 answers)
Closed 5 years ago.
I'd read that size specifier is mandatory while declaring an array if it is not explicitly initialized,
but the piece of code given compiles and runs successfully?
main()
{
int r;
scanf("%d",&r);
char array[r]; //memory is not allocated at compile as value of variable is not known
scanf("%s",array);
printf(array);
}
This is valid code that makes use of Variable-Length Array feature of C99.
As long as r is properly set by scanf, it is legal to use it in allocation of char array[r].
There are several issues that need to be addressed, though:
If scanf returns zero, r remains uninitialized. Using it for specify array size in a declaration would be illegal.
If scanf read a negative number, using it as array size would be illegal.
If scanf read a number that is too large for your system's automatic memory space, you would run into undefined behavior.
The last point is very important: your system may have enough memory for the array, but not enough space in the automatic memory (often called "stack") to allocate your array. This can result in a crash.
A better approach is to allocate your array dynamically with malloc, and free it once you are done with it.
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:
Variable Sized Arrays vs calloc in C
(5 answers)
Closed 7 years ago.
I was amazed to see that this code is working. I couldn't figure out why
#include<stdio.h>
int main(){
int row,col,i,j;
scanf("%d %d",&row,&col);
int a[row][col];
for(i=0;i<row;i++)
for(j=0;j<col;j++)
scanf("%d",&a[i][j]);
for(i=0;i<row;i++){
for(j=0;j<col;j++)
printf("%d ",a[i][j]);
printf("\n");
}
}
Since C is a compiled language then How it is allocating memory for the array a[row][col] ? Since at the time of compilation the value of row and column are not known, then how it is able to make machine code and set the address space for the program? Why this is working as an interpreter language would have worked, If this is a way to create a dynamic array then why are we taught to use malloc for creating dynamic array in C.
Variable-length arrays have been a standard feature of C since C99.
How it is allocating memory for the array a[row][col]
Once the value of row and col is known, there is no problem for the compiled code to make this allocation in the automatic storage area (commonly referred to as "the stack").
how it is able to make machine code and set the address space for the program?
The compiler squirrels away the values of row and col for internal use by machine code that it generates. Instructions that reference a[i][j] look up the sizes, do the math, add the offset, and get the address, as if row and col were known at compile time.
The feature does change a few other things - for example, sizeof is no longer a purely compile-time operation, because the size of VLAs need to be computed at run-time.
why are we taught to use malloc for creating dynamic array in C.
malloc gives you more flexibility than a VLA. For example, you can return a malloc-created array from your function, while VLA gets automatically deallocated as soon as the function finishes. In addition, malloc is less likely to run your program out of memory, because dynamic storage area is more generously sized than the automatic one.
For example, if you try to enter 2000 2000 for your program, it is likely going to crash. Yet it would have no problem allocating the same amount of memory with malloc:
int (*a)[col] = malloc(row*col*sizeof(int));
That's feature of C99. The reason to use malloc anyway is that it allocates space not on the stack, but the heap - and the heap is where the 'heavy' data should be stored, as the stack space is severely limited. More than that; failure to do a stack allocation typically crashes the program - while allocating with malloc returns a NULL pointer, which allows you to proceed in elegant fashion.
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 :-)