views:

226

answers:

9

I get this when I was trying something (just for understanding). Please explain this behavior:


First attempt:

void main()    
{  
    char src[] = "vinay";
    int i;
    // char name[5] = "test";
    char *name=  "abcde";
    printf("%s \n", name);
    if (*(name+5) == '\0')
        printf("6th char is null\n");
    strcpy(name,src);
    printf("printcheck \n");
    for (i=0 ; i <6 ; i++)  
    {
        printf("%c \n", *(name+i));
    }
    printf("%s \n",name);    
}

Output:

abcde 
6th char is null
zsh: 16644 segmentation fault (core dumped)  a.out


Second attempt:

void main()
{
    char src[] = "vinay";
    int i;
    char name[] = "pqrst";
    //char *name=  "abcde";
    printf("%s \n", name);

    if (*(name+5) == '\0')    
        printf("6th char is null\n");

    strcpy(name,src);
    printf("printcheck \n");

    for (i=0 ; i <6 ; i++)
    {
        printf("%c \n", *(name+i));
    }

    printf("%s \n",name);
}

Output:

pqrst 
6th char is null
printcheck     
v     
i   
n   
a     
y 
vinay

===========================================================================================

Question: Why does it crash on attempt 1? I was trying this on a Solaris machine Kernel version: SunOS 5.8 Generic 117350-43 Oct 2006

A: 

Looks like name is just a pointer to some memory and you need to allocate that space either using [] or the new keyword.

JonH
The OP is using C.
Aviral Dasgupta
+5  A: 
char* name = "abcde";

allocates a pointer to constant memory space you don't have write access to.

char name[] = "vinay";

allocates a writable array.

Grumdrig
A: 

In 1st attempt name is a pointer to const memory resource. In the 2nd attempt you have change that and the allocation is done before putting the text into that memory area.

Dynamic allocation is done with:

char * buffer = malloc(STRING_SIZE);

or

char buffer[STRING_SIZE];
Andrejs Cainikovs
+8  A: 

Because this kind of operation:

char name[] = "pqrst";

Copies a constant string to an array on the stack. You are free to modify your local copy.

However, this kind of operation:

char *name=  "abcde";

Simply assign the address of the string to the pointer. Attempting to modify that string is attempting to modify a constant string, which is located in a protected region and thus is not allowed.

RichN
+1  A: 

The problem is with this line:

char* name = "abcde";

The string "abcde" is a static const string, which is embedded into a portion of your executable that it is not legal to write to. When you then do strcpy(name, src), strcpy attempts to write into the static portion of memory, which causes an access violation.

On the other hand, when you write this:

char[] name = "abcde";

then name is an array allocated within your local function's stack. You can always write to your stack, so this works just fine.

JSBangs
+5  A: 

String literals are not modifiable (under penalty of Undefined Behaviour). When you declare a pointer to them, you really should make it const

const char *name = "string literal";

Quote from the Standard:

6.4.5 String literals

6 .... If the program attempts to modify such an array,
  the behavior is undefined.
pmg
A: 

The reason it may not necessarily is you have not allocated space for the variable name. You're dumping vinay over the top of a random area on the stack, which may well be reserved for something else. Use malloc to allocate space for your string, and you should be fine :)

Mark Mayo
A: 

The string constants ("abcde") are probably in a read-only data segment and thus cannot be written to with

char src[] = "vinay";
char *name = "abcde";
[...]
strcpy(name, src); /* copy string src to whatever name points to */

Copying to a readonly memory location will give you a segfault.

The second program works, as now the target memory area is located where all the local variables are, and that memory area (the stack) is writable.

char src[] = "vinay";
char name[] = "abcde";
[...]
strcpy(name, src); /* copy string src to the memory area designated by name */
ndim
A: 

Attempt 1 fails because you are modifying memory which was initialized by the compiler. Using quotes as in char *name = "something" to define a string in constant memory space (not on the stack as in char name[] = "vinay" You should not be modifying it, and therefore you get a segmentation fault as you are trying to write to a non-writable area. If you want to use a char * instead and make it modifyable, allocate the memory yourself instead:

char *name = NULL; 
name = (char *) malloc(6);

but don't forget to free() it later!

jamuraa