im new to the C language and im trying to understand the basic of memory allocation . here I have two function that produce the exact same result, but only one of them using the malloc() function and the other one is not.
FIRST FUNCTION
int First()
{
int arr[] = {11, 13, 7, 12, 16};
int length = sizeof(arr) / sizeof(int);
// NOT using malloc
int arr2[length];
// Initialize elements to 0
for (int i=0; i < length; i )
arr2[i] = 0;
// Print results
for (int i = 0; i < length; i )
printf("%d ", arr2[i]);
return 0;
}
SECOND FUNCTION
int Second()
{
int arr[] = {11, 13, 7, 12, 16};
int length = sizeof(arr) / sizeof(int);
int *arr2;
// Here im using malloc to allocate memory
arr2 = malloc(sizeof *arr2 * length);
// Initialize elements to 0
for (int i=0; i < length; i )
arr2[i] = 0;
// Print results
for (int i = 0; i < length; i )
printf("%d ", arr2[i]);
return 1;
}
Both of this two functions will print: 0 0 0 0 0
.
What are the differences between this two approaches ? I know that using malloc(or memset) to allocate memory based on a variable is the right approach , but im trying to understand why exactly ?
Thanks!
CodePudding user response:
The difference is the lifetime of the objects. Basically it means when the object is valid and it can be accessed.
Generally, there are three lifetime types:
Static
The object is valid all the time
Example:
int* foo(void) {
static int A[10];
return A;
}
Array A
is always valid. It can be safely returned from a function.
Automatic
The object is valid from its definition to end of the block where it was declared
Example:
void foo(void) {
int *p;
{
int A[10];
... A is valid here ...
p = &A[0]; // p points to
*p = 42; // still valid
}
// A is no longer valid
*p = 666; // UB strikes, expect everything
}
A pointers to automatic objects should never be returned from functions because they would point to non-existing objects. Any use of value of such a pointer triggers Undefined behavior.
Dynamic
The lifetime is controlled by the program. It starts with memory allocation via malloc()
or similar functions. It ends when calling free()
on the pointer to this object. Dynamic object can only be accessed via a pointer.
Example:
int* foo(void) {
int *p;
{
p = malloc(sizeof(int[10])); // p points to an object for 10 ints
*p = 42; // still valid
}
*p = 43; // still valid
return p; // still valid though function has returned
}
int *p = foo();
*p = 44;
free(p); // release
*p = 666; // UB strikes, expect everything
Forgetting to call free()
usually leads to the memory leak.
CodePudding user response:
The second function has a memory leak because the dynamically allocated array was not freed.
The first function is conditionally supported by compilers due to using a variable length array. Also if the size of the array is big then it can occur such a way that the array will not be allocated.
And the function memset
allocates nothing.
CodePudding user response:
One of the differences that I can come up with is the sizes of the arrays.
In your first function, if you put sizeof(arr2)
at the end, you will get 20. But at your second function, when you put sizeof(arr2)
you will get 8. (Size of a pointer depends on your computer. A pointer's size is 8 bytes in 64-bit mode. And 4 bytes in 32-bit mode.)