1

Below is the C program which I am trying out. It allocates the memory for the required number of elements as per the user input, gets the elements for the user, prints the elements & the sum.

I am freeing the allocated memory using the free function before the use ptr. However, it's not throwing any error and I am able to compile/run, print the array and also the sum, successfully. My understanding of malloc and free is that if we free the allocated memory and try to access it, it should throw an error at compile time? Kindly clarify this doubt. Thank you.

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

int main(void){
    int num=0;
    int *ptr=NULL;
    int sum=0;

    printf("Enter number of elements in an array: \n");
    scanf("%d",&num);

    ptr = (int *)malloc(num*sizeof(int));

    if (ptr==NULL){
        printf("Error: unable to allocate memory\n");
        exit(EXIT_FAILURE);
    }

    free(ptr); //ERROR NOT TRIGGERED

    printf("Enter the elements of the array: \n");

    for(int i=0;i<num;i++){
        scanf("%d",(ptr+i));
        sum += *(ptr+i);
    }

    printf("\nArray Elements are: \n");

    for(int i=0;i<num;i++){
        printf("%d ",*(ptr+i));
    }

    printf("\nSum of array elements are: %d\n", sum);
    return 0;
}
Kanan Jarrus
  • 607
  • 1
  • 12
  • 26

4 Answers4

4

Since you have successfully allocated the memory, there's absolutely no reason that free should trigger an error. However, using the pointer after that is undefined behavior which means that anything may happen, including working correctly, crashing, formating your hard drive or sending offensive images to your bosses email. Granted, that two last things would never happen, but nothing in the C specification says that it cannot. Undefined behavior is undefined.

Invoking free on a pointer basically means that you promise not to use the memory again. If you break that promise, well, take the consequences.

It's not strange that it compiles. If this goes wrong, it will do so at runtime.

klutt
  • 30,332
  • 17
  • 55
  • 95
  • Well -- formatting your hard drive or sending offensive images to your bosses email may be a bit of a stretch... (unless you are on windoze) But, metaphorically speaking that's a correct analogy. – David C. Rankin Jan 04 '18 at 06:27
  • I once formatted a hard drive due to a programming error. ( DOS mouse service is 0x33, BIOS disk is 0x21, I typed 33 for mouse) – Jasen Jan 04 '18 at 07:17
  • If undefined behavior means it can send offensive images to your boss, then it should also be able to print next best selling book to standard output. Maybe it is not that bad? –  Jan 04 '18 at 13:56
3

Using/accessing allocated memory after it has been freed is undefined behavior.

From C Standards#J.2 Undefined behavior:

The value of a pointer that refers to space deallocated by a call to the free or realloc function is used (7.22.3).

Check following:

1. Freeing memory

2. Using freed memory


Additional:

Do not cast the return value of malloc.

H.S.
  • 11,654
  • 2
  • 15
  • 32
0

This is undefined behavior. (because you are trying to access some memory which is freed already. This might have crashed your program immediately. Or It may appear to work just fine, but you shouldn't be relying on this.).

And no it doesn't. You are on your own here. Basically you have to keep track of whether you are using an already freed memory. And as it is undefined behavior - you must avoid it.

Also the thing is, you have expected that error will occur when you have freed it. This is not the case. You can free it anywhere (unless you haven't freed it). Compiler won't complain that you are going to use it after this - so don't call free.

user2736738
  • 30,591
  • 5
  • 42
  • 56
0

Just to add one slightly different perspective to the fine answers already given:

Your expectation that and error would be thrown likely comes from familiarity languages that have active memory management (e.g. reference counting or garbage collection), complex object-types (e.g. array objects, key-value hash tables), and variables that are references to entities (objects, structs, functions, variables, etc).

An important thing to understand about c is that in comparison to many other popular languages (say Java, or scripting languages like Javascript or Python), is that it's quite low-level (compiled to platform-specific operations!) and because of this 1) there isn't a mechanism watching whether a particular instruction is manipulating memory safely (there is no runtime environment beyond what is compiled) and 2) in c, the value of a pointer is not a reference to an entity, but a memory address, and it's always a valid operation to dereference an address or assign a new value there

In your simple case it's likely that the compiler could anticipate the issue and issue a warning (and there are in fact memory debugging tools that can help with this; valgrind, for example). But one could imagine setting your pointer equal to a different location before reading it out, or doing so as the result of a complicated conditional expression. It would be difficult for a compiler to catch this type of error in general at compile-time.

The one related runtime error you might encounter is imposed by the operating system. If you try to reach memory outside of that allocated for your program, your program is likely to exit with a segmentation fault due to operating system memory compartmentalization.

In any event, I thought this might provide some background as to why accessing freed memory isn't just undefined to be mysterious. It's a result of the simplicity of the language.

Joshua R.
  • 2,282
  • 1
  • 18
  • 21