Home > Blockchain >  Dynamic memory allocation vs Using pointer
Dynamic memory allocation vs Using pointer

Time:05-09

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.)

  • Related