简体   繁体   中英

Error (Segmentation Fault) while reusing a dangling or null pointer

#include<stdlib.h>
#include<string.h>
int main ( void )
{
  char *title=NULL;
  title = (char *) malloc(15);
  strcpy(title, "C Programming");
  printf("String = %c", *title);
  free(title); 
//   title=NULL;    //or title = 0;
  strcpy(title, "C++");
  printf(" %s", title);
  return 0;
}

When I uncomment the "title=NULL" line the program crashes with a segmentation fault; can someone explain the behavior

prints "String = C C++" otherwise

If your code dereferences a dangling or null pointer, the behavior is undefined - anything can happen. The two possible behaviors ("it works as expected" and "it crashes") are actually most common manifestations of undefined behavior.

Sometimes, you can rationalize undefined behavior - like in this case. But you cannot always count on it being understandable.

  • If your code tries to write stuff into a null address, it crashes because the operating system can detect that. It's very easy (null pointer points to a memory page which is not readable and not writable) and useful (a good debugger will stop directly at the offending line of code).
  • If your code tries to reuse a dangling pointer, the address it points to is typically still writable - free will not tell the operating system that it is now dangling. free will only edit some bookkeeping data structures, so the freed address would be available for future allocation. It's not easy to cause a crash on accessing a dangling pointer, because OS can manage memory access only on a page granularity, which can be 4 KiB or something like that.

90% of the question is red herring . The entire question can be restated in one line:

When I do this: title=NULL; strcpy(title, "C++"); My program crashes. Why?

The above code attempts to write bytes to the memory address referrenced by a null pointer. This is by definition undefined behavior. Undefined behavior means that anything may happen, for example bowls of petunias and sperm whales might start falling from the sky, but in the vast majority of execution environments out there, and certainly in your execution environment, the memory address referenced by null pointers is not writable, so this will always result in the exact behavior that you are experiencing: a segmentation fault.

Furthermore, to address the remainder of the question, when the line setting the pointer to NULL is commented out, then you are writing to a memory location which has been freed. Since it has been freed, it should never be accessed again, and accessing it is again undefined behavior, only in this case there are no mechanisms to detect the misuse, so it just happens to work by sheer coincidence. Try running the same program in a different environment, and there will be bowls of petunias and sperm whales falling from the sky.

It is undefined behavior. You tell OS that your program doesn't need memory anymore by doing free(title) but that doesn't mean that memory is immediately taken from your process. Instead title still holds address of (now freed and not accounted for) memory and subsequent strcpy() (depending on OS and its memory usage policy) might be able to write into that memory and printf() will get address (again freed and unaccounted for) and will print characters until it reaches first \0 put there by strcpy() .

When you properly set title to NULL after freeing it, further functions ( strcpy() here) which expect pointer to allocated memory will get invalid input and fail (with segmentation fault).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM