Search code examples
cpointersmallocfreememory-mapped-files

C: Pointer arithmetic and malloc() - NO GO?


Getting familiar with pointers, I came across the section of dynamic memory allocation using malloc() as well as free(). I would like to have confirmation or correction on my understanding of this topic.

Until now, I understood the big benefits of pointers to be two-fold:

  1. Call by reference (i.e. variables outside a function can be accessed and altered using a pointer without the need of the variables being global).
  2. Using pointer arithmetic, it is a very convenient and code-efficient way of going through an array (e.g. a char array as a string), accessing and manipulating data.

Talking about malloc(), I kind of feel that pointer arithmetic can become quite dangerous if the pointer address is not being reset. Given the example below, I created two pointers ptr and ptr1 using malloc(). I understand that the two malloc() functions allocate two memory blocks, each as big as size*sizeof(int), so this is reserved memory and the addresses of the first elements of these two blocks are given to ptr and ptr1.

Using the first for loop, I am assigning values into the memory locations using pointers. ptr uses pointer arithmetic, ptr1 uses array arithmetic (If I can call it that way).

At the end of the for loop, ptr does not point to the address of the first element of the reserved memory block, and must be reset back in order to point to the address of the first element.

The second for loop prints the data stort in the two memory blocks. There, I do not reset ptr to point to the address of the first element in the memory.

Now the big question: Using free(ptr), free() receives a pointer that points to a certain address (other than the start address of the memory block that was reserved). Do I understand correctly that writing free(ptr), I will now release a different memory block of size*sizeof(int) and I might release some sensitive data that should not be released?

Is that correct understood? If so, would it advisable to always use array arithmetic when using pointer in connection with malloc()?

Thank you, Alex

#include <stdio.h>
#include <stdlib.h>

int main()
{
int size = 0;
printf("Enter the array size: ");
scanf("%d",&size);

int * ptr = (int *)malloc(size*sizeof(int));
int * ptr1 = (int *)malloc(size*sizeof(int));

int i = 0;
// First for loop
for( ; i<size;i++)
{
    *ptr = i;
    ++ptr;
    *(&ptr1[i]) = i;
}

ptr = ptr-size; // Resetting to the start address

// Second for loop
for(i = 0; i<size;i++)
{
    printf("%d\t\t",*ptr);
    ptr++;
    printf("%d\n",*(&ptr1[i]));
}

free(ptr);  // Is the correct memory block now freed?
free(ptr1);
return 0;
}

Solution

  • Your program has undefined behavior. The pointer value passed to free() must be exactly equal to a value obtained from malloc(), calloc(), or realloc(). From cppreference.com:

    The behavior is undefined if the value of ptr does not equal a value returned earlier by malloc(), calloc(), realloc(), or aligned_alloc() (since C11).

    So keep an unadulterated pointer to your allocation to pass to free(), and use a copy for the pointer arithmetic.