1

To gain better understanding of malloc() and realloc() I'm trying to run the following code:

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

int main () {
   char *str;

   str = malloc(20);
   str = strcpy(str, "inf110_malloc_test");
   printf("String = %s,  Address = %u\n", str, str);

   str = realloc(str, 25);
   str = strcat(str, " is dene perfectly.");
   printf("String = %s  Address = %u\n", str, str);

   free(str);
   return(0);
}

Output:

String = inf110_malloc_test,  Address = 1840192
String = inf110_malloc_test is dene perfectly.  Address = 1840192

The problem is that the code is running just fine even if I pass NULL argument to malloc().

...
str = malloc(NULL);
...

I read on cplusplus.com the following:

To avoid overflows, the size of the array pointed by destination shall be long enough to contain the same C string as source (including the terminating null character), and should not overlap in memory with source.

Why the program doesn't crash at this point? Do strcpy() allocate some enough memory automatically?

muhammed-shihebi
  • 134
  • 2
  • 11
  • C doesn't stop you from shooting yourself in the foot. And it also doesn't guarantee what will happen when you do. This is known as "undefined behaviour" in C. When UB is encountered the program may crash, or it may appear to work, or any other behaviour. – kaylum Apr 04 '20 at 21:15
  • It actually does thank you. @kaylum – muhammed-shihebi Apr 04 '20 at 21:24
  • Please do not tag questions with C and C++ unless you are asking about some difference between the languages or some interaction between them, such as calling routines in one from another. – Eric Postpischil Apr 04 '20 at 21:28
  • I don't think this is the case here. One could miscalculating and this could cause a serious danger in some situations. @Useless – muhammed-shihebi Apr 04 '20 at 21:29
  • Do not call `malloc` with `NULL` as an argument. `NULL` is intended to stand for a null pointer. For historic reasons, it may be defined as `0`, so `malloc(NULL)` will effectively be `malloc(0)` and will not generate an immediate error. However, the resulting behavior is implementation-defined: It may return a null pointer or may return a non-null pointer, but the pointer shall not be used to access an object. – Eric Postpischil Apr 04 '20 at 21:30
  • You specifically asked why you can copy a string into the pointed returned by `malloc(0)` (see the comment above) - and the answer is that if it returns a valid record of zero size and you overflow it - _this is not checked for you_. So don't do it. It _is_ a real problem, which is why _you_ have to be careful to avoid it. – Useless Apr 04 '20 at 21:33
  • 1
    Yes, miscalculating the memory requirements could cause a serious problem in programs. Nonetheless, neither the C nor C++ standard requires implementations of C or C++ to protect you from this. The standards **do not define** what happens when you overflow an array. C and C++ implementations are permitted to crash when this happens, and they are permitted to let you corrupt memory. Most implementations do not go to much effort to detect array overflows, and your program will crash only if it tries a memory access not permitted by the memory mapping. – Eric Postpischil Apr 04 '20 at 21:33

1 Answers1

1

The problem is that the code is running just fine even if I pass NULL argument to malloc().

It is undefined behavior, no hesitation.

realloc'ed memory field either can be at the same address of malloc'ed one or be at a new memory address subject to space sufficiency therein after the data is moved.

I would understand better, and prefer to write realloc(20 + 5), consequently.