user1889966
user1889966

Reputation: 165

Calling free( ) in C

What exactly is happening when I call free(a)? I know it is freeing the memory used, but does this also mean that the data stored in array a can no longer be accessed (therefore, not being able to call copyArray)?

int *a = (int *) malloc(sizeof(int) * numberOfInts);
for (i = 0; i < numberOfInts; i++) {
        a[i] = random();
        printf("%d\n", a[i]);
    }
    free(a);
    copyArray(*a++, numberOfInts);

Upvotes: 2

Views: 5697

Answers (7)

that other guy
that other guy

Reputation: 123750

What exactly is happening when I call free(a)?

This is implementation specific. As an example, with Linux and glibc, one of several things can happen:

If the memory was allocated in a block of 128k or more, glibc will have allocated a new memory area (specifically, a copy-on-write mmap of /dev/zero). When it's freed, the memory area is simply deallocated (munmap'd)and disappears. Further accesses will crash.

If the allocated memory was smaller, it will go on the heap. The heap is a single memory area starting at a fixed address, and is of a size that the process can shrink or increase (with sbrk).

The memory allocator keeps tracks of which pieces of this area is allocated. The first time something is allocated, the size of heap is increased, and the memory is appended to the end in this new space.

If you free such a block of memory, at the end of the heap, the heap size can be reduced, thus making the memory invalid and making further accesses crash. The allocator will not increase or decrease the heap size for just a few bytes though, so at that point it depends on the size of the allocation and the number of blocks freed. It might be accessible, and it might not be.

If you allocate ten blocks of memory and free the first nine, you end up with an unused area in the heap. Since you can only modify the heap size by setting the end address, you can't really do anything about it. The memory is still valid, and accessing it will still work. You will probably even find your original data in it, and will be able to continue as if nothing happened.

However, as new memory is allocated, malloc will try to put it in this unused area, thus letting other data overwrite what was originally there. Setting an int in your free'd array could then overwrite a pointer in a completely unrelated part of your program, and hilarity and debugging ensues.

tl;dr: Don't access free'd memory!

Upvotes: 4

ed_me
ed_me

Reputation: 3508

When you are using 'malloc', you are dynamically allocating a block of memory pointed at by a. Typically, although implementation specific, dynamically allocated memory is stored on the heap. Without calling free, you will be leaking memory when a goes out of scope.

The block of memory that you created, which is pointed at by a, can no longer be used after a call to free. This would have very unpredictable behaviour and could potentially cause a segmentation fault.

Upvotes: 0

Aniket Inge
Aniket Inge

Reputation: 25733

When you call free(a) it means that the memory has been flagged for re-use. So, writing an array to a will still work, but it is undefined behavior. Chances are it will be overwritten later without you being notified about it.

Secondly do not cast the return value of malloc() in C.

do this:

int *a = malloc(sizeof(*a) * numberOfInts);

Also, in C99, you have the provision for VLAs in which you can do this:

printf("Enter array length: ");
scanf("%d",&numberOfInts);
int a[numberOfInts];

and you will not have to manually de-allocate these arrays. Note however, there is a limit to the length you can have for VLAs

Upvotes: 0

user529758
user529758

Reputation:

but does this also mean that the data stored in array a can no longer be accessed

Yes - more precisely, accessing it (i. e. dereferencing an invalid pointer) results in undefined behavior, so your program can do anything (including crashing, that it probably will).

Upvotes: 1

Mahesh
Mahesh

Reputation: 34665

You should not access the memory locations that are freed. Yes, the data stored in those locations can no longer be accessed. But accessing freed locations leads to undefined behavior.

Upvotes: 1

Emanuele Paolini
Emanuele Paolini

Reputation: 10172

When the memory is freed you cannot make any assumption to what it might contain. So you should not access it anymore.

Upvotes: 0

Carl Norum
Carl Norum

Reputation: 225282

Yes, that's exactly what it means. As soon as you call free() the memory in question is returned for use by the operating system. It might still look like it's working, but you're causing undefined behaviour.

Upvotes: 1

Related Questions