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
source to share
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.
source to share
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.
source to share
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.
source to share
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 :)
source to share
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 */
source to share
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!
source to share