Please explain this behavior with character arrays/strings in C
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[] = "vina开发者_JS百科y";
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
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.
char* name = "abcde";
allocates a pointer to constant memory space you don't have write access to.
char name[] = "vinay";
allocates a writable array.
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.
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.
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];
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 :)
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!
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 */
精彩评论