kunal18
kunal18

Reputation: 1926

program crash while using char*

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

Answers (5)

Mahmoud Emam
Mahmoud Emam

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

Mihai Maruseac
Mihai Maruseac

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:

enter image description here

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

elyashiv
elyashiv

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

Mike
Mike

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

Daniel Fischer
Daniel Fischer

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

Related Questions