Explain this behavior by character arrays / strings in C

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


First try:

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 try:

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 when trying 1? I tried to do this on a Solaris machine Kernel version: SunOS 5.8 Generic 117350 - 43 Oct 2006

+2


source to share


8 answers


Because such an operation:

char name[] = "pqrst";

      

Copies a constant string to an array on the stack. You can change your local copy.



However, this kind of operation:

char *name=  "abcde";

      

Just assign the string address to the pointer. An attempt to change this string tries to change a constant string that is in the protected area and therefore not allowed.

+8


source


char* name = "abcde";

      

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



char name[] = "vinay"; 

      

allocates a writable array.

+5


source


String literals are not modified (compromised by Undefined Behavior ). When you declare a pointer to them you should really do thisconst

const char *name = "string literal";

      

Quoting from the standard:

6.4.5 String literals

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

      

+5


source


The problem with this line:

char* name = "abcde";

      

A string "abcde"

is a static constant string that is embedded in a part of your executable that is not allowed to write to. When you execute strcpy(name, src)

, it strcpy

tries to write to a 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 on your local function stack. You can always write to your stack, so this works great.

+1


source


On the first try, the name is a pointer to a persistent memory resource. On your 2nd try, you have a change and the selection is done before the text is put into that memory area.

Dynamic selection is done with

char * buffer = malloc(STRING_SIZE);

      

or

char buffer[STRING_SIZE];

      

0


source


The reason this is not required is because you did not allocate space for the variable name. You are dumping vinay over the top of a random region in the stack, which may very well be reserved for something else. Use malloc to allocate space for your string and you should be fine :)

0


source


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

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

      

Copying to a read-only memory location will give you a segfault.

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

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

      

0


source


Attempt 1 fails because you are modifying memory that was initialized by the compiler. Using quotes, as in char *name = "something"

, to define a string in a constant memory space (not on the stack as in char name[] = "vinay"

. You shouldn't modify it, and therefore you get a segmentation fault as you are trying to write it to a non-writable space If you want to use char *

and make it instead modifiable, allocate memory yourself:

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

      

but don't forget free()

later!

0


source







All Articles