How can I use this unallocated memory?

Why am I not getting an error when using the following program?

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

int main(int argc, char *argv[]){
  char *pStr = (char*) malloc(25); 
  free(pStr); 
  strcpy(pStr, "foo");
  printf("%s\n", pStr);
  return 0;
}

      

Shouldn't you free(pStr)

stop me from writing to this address? Don't I need to allocate space one more time before I can use it?

+3


source to share


4 answers


free

doesn't prevent you from doing anything as long as the thing is syntactically correct. This way, you still more than can copy to char*

, as you could if you never allocated memory in the first place. But this behavior is undefined and is responsible (read: most likely) to make your program crash or do something wrong without warning.

For example, if your compiler is doing some optimizations, it might reorder the instructions to save time. Since you have freed memory, the compiler might think it is safe to allocate memory at this location for some other data that will be generated later. If the optimizer moves this allocation and writes up to yours strcpy

here, you can overwrite the object that is stored there.

Consider this code:



int main(int arc, char *argv[]){
    char* pStr = (char*) malloc(25);
    free(pStr);
    strcpy(pStr, "foo");
    printf("%s\n", pStr);
    int* a = (int*) malloc(sizeof(int));
    *a = 36;
    printf("%d\n", *a);
}

      

Since you wrote to unallocated memory, you cannot be sure that any of the printf

. Perhaps 36 could overwrite some string "foo". The line "foo" could overwrite the value 36 it points to a

. Or maybe none of them affect the other, and your program works seemingly just fine until you change the name of some variable and recompile, and for some reason everything messes up, even if you changed nothing.

Moral of the story: you're right that you shouldn't write to free

d memory; however, you are wrong that you cannot write to free

d memory. C does not check for this condition and assumes that you are trying to do something unusual. If you know exactly how your compiler is optimized and where it allocates memory when called malloc

, you can know that writing to unallocated memory is safe in a particular case, and C does not prevent you from doing it. But 99.999% of the time when you don't know everything, just don't do it.

+9


source


This is undefined behavior . And what really happens is implementation specifics.

In practice, free

it is very common to mark a freed block of memory as reusable for the future malloc

-s.



See also this ...

+5


source


Other answers have indicated undefined behavior, so the compiler is not required to make any diagnostics. However, if you have a modern version gcc

( > = 4.8 ) or clang

, then it AddressSanitizer

might be helpful in case of this "after use" error:

$ gcc -ansi -pedantic -fsanitize=address check.c
$ ./a.out 
=================================================================
==2193== ERROR: AddressSanitizer: heap-use-after-free on address 0x60060000efe0 at pc 0x4009a8 bp 0x7fff62e22bc0 sp 0x7fff62e22bb8
...

      

A common defensive software "trick" is to assign NULL

immediately after the call free()

:

free(pStr), pStr = NULL;

With him he'll probably get "Segmentation fault"

with a break pStr

in GNU / Linux, but there is no guarantee on that.

+3


source


Understand the answer to your question that you need to understand the memory allocation process. In a general sense, malloc / free are library functions. They manage a pool of memory that is allocated from operating system services.

[with increased simplification]

Your first malloc finds an empty pool. It then calls the operating system system service to add pages to the process, which is added to the pool. Malloc then returns a block of memory from that pool.

The free call returns the block to the pool. It remains a valid block of memory in the pool.

If you access a free address, the memory is still there. However, you # $ @ $ add the malloc memory array. This access will eventually lead you to # $ # $.

0


source







All Articles