0
#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

  • `title=NULL; ` is there to avoid the behavior you are just facing, why are you trying to make something to work when it should not, you need a `malloc` again to make it work, since you `free`'d the previous memory – IrAM Jan 03 '21 at 11:45
  • `free(title); // title=NULL; //or title = 0; strcpy(title, "C++");` You are using memory that you freed. So you are getting segmentation fault - which is the error you get when using memory that don't belong to you. – KamilCuk Jan 03 '21 at 11:49
  • @IrAM It was an MCQ question to tell the output of the program, I just wanted to know what goes wrong when a string is copied to that pointer. – Sumit Velaskar Jan 03 '21 at 11:49
  • `strcpy(title, "C++");` results in undefined behaviour, when `title` has been freed and not set to `NULL` (undefined behaviour includes "apparently working fine"). `strcpy(NULL, "C++");`, although being undefined behaviour, ends up in a segfault on virtually any modern system. – Jabberwocky Jan 03 '21 at 11:49
  • output is : Undefined – IrAM Jan 03 '21 at 11:50

3 Answers3

2

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.
anatolyg
  • 26,506
  • 9
  • 60
  • 134
1

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.

Mike Nakis
  • 56,297
  • 11
  • 110
  • 142
0

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).

blami
  • 6,588
  • 2
  • 23
  • 31