Reputation: 1926
While running following code, my program crashes unexpectedly!
#include<stdio.h>
#include<string.h>
int main(){
char *str = NULL;
strcpy(str, "swami");
printf("%s", str);
return 0;
}
But if I do like this:
#include<stdio.h>
#include<string.h>
int main(){
char *str;
strcpy(str, "swami");
printf("%s", str);
return 0;
}
This code works fine and generates correct output!
I am using gcc compiler(codeblocks IDE). Also, both the codes lead to program crash in DevCpp. Can anyone please explain me why this is so!?
Upvotes: 1
Views: 1658
Reputation: 1527
Because NULL
is #define NULL ((void *)0)
in <stdlib.h>
. So, you try to write in invalid memory address that make your program crash.
Upvotes: 2
Reputation: 21460
You cannot write to NULL
pointers.
In the second case, it happened that your pointer was randomly initialized to a valid location in your program's memory. That is why you could do a strcpy
into it.
Change both programs to have
str = malloc(size)
or the option with calloc
before the strcpy
. (size
is the size of the space you want to reserve.)
As per comment, you can also change the declaration of str
to be char str[6]
(or more).
Last edit: I'll present you this picture showing the memory of your program and the pointers:
The gray areas and the red one are forbidden (you cannot write or read from them; the top gray one is for kernel memory while the others are spaces not yet reclaimed). The red area at the bottom is the special 0 page. Since NULL
is 0
your str = NULL
will point to this and your program will fail.
If you don't assign anything to str
it will end up pointing randomly. It can still point to the red area or to a grey area -> your program will fail. It could point to a green or blue (both hues) area, making your program work (excepting the cases where it is pointing to a read-only location and you write to it). Allocating area for the pointer makes it point to the green area, enlarging it to the top.
The other option, with str[6]
enlarges the stack area to bottom. All local variables have space reserved into the stack while all space allocated with malloc
, realloc
, calloc
and other friends goes into the heap.
Lastly, have a look at a blog article about the difference between char[]
and char *
.
PS: If you'd want to use a GNU extension you can look into the asprintf
function. It would allocate space for a string and write some content there:
asprintf(&str, "swami");
or
asprintf(&str, "%d + %d == %d\n", 1, 2, 3);
But, if you want portability, you'd stay away from this function.
Upvotes: 23
Reputation: 3691
strcpy
just copies, not generating space for it.
in the first case you tried to write the string to the beginning of the code segment: not a good idea.
in the second case, you started writing the string to somewhere, and in your case didn't crash do to luck and maybe compiler help.
you should do one of the following:
a. allocate memory: str = new char[10]
b. use strdup
witch well duplicate the string into a new location.
Upvotes: 1
Reputation: 49463
Read this link
//destination =Pointer to the destination array where the content is to be copied.
char * strcpy ( char * destination, const char * source );
You're setting destination to NULL, so you're trying to copy source to NULL. That's why it crashes. You should be setting some memory asside to copy the string to instead.
int main(){
char *str=malloc(6); //enough for "swami"+'\0'
strcpy(str, "swami");
printf("%s", str);
return 0;
}
Upvotes: 1
Reputation: 183968
In neither version have you allocated memory to copy the string to, so both invoke undefined behaviour. The first one crashes because you explicitly initialised str
to NULL
, so the strcpy
dereferences a NULL
pointer, that crashes on most systems. In the second, str
points to arbitrary memory, dereferencing that uninitialised pointer may or may not crash.
Upvotes: 4