This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Memory Allocation char* and char[]
Why does the following program give a Segmentation fault in run-time ?
#include <stdio.h>
#include <string.h>
#include <malloc.h>
main()
{
char * str = "Have a. nice, day :)";
char * ptr;
ptr = strtok( str, " .,");
printf("%s",ptr);
}
But if I use char str[] = "Have a. nice, day :)"; it gives me the output. Why is that i get the error even though strtok definition is char* strcpy( char * , const char * ) ???~
strtok modifies the argument, str points to a string literal, modifying a string literal causes undefined behavior. Initializing a non-const char* with a string literal is in fact deprecated.
When you write str[], str becomes a mutable array initialized with the string.
strtok modifies the string passed to it. I suspect it has something to do with char * = "literal string" giving you a pointer to the string in the .data section, while char[] = "literal string" allocates a buffer on the stack, and copies the initial contents from the .data section.
Related
This question already has answers here:
Why do I get a segmentation fault when writing to a "char *s" initialized with a string literal, but not "char s[]"?
(19 answers)
Closed 9 years ago.
I have a problem with the c function 'strcpy' that I have not been able to figure out.
it involves copying to a char *[] like Argv (but not actually Argv). I can copy out of the structure but not in. But only if I initially declare the entire Argv Structure in a single go.
I assume that a char *[] is and array of char*.
Here is a simple demo program of the issue:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char FN[]="BBBB";
char *TL[]={
"a0 ",
"a1 ",
"a2 ",
"a3 ",
"a4 ",
"a5 "};
char BN[]="c1 ";
char N0[]="N0 ";
char N1[]="N1 ";
char N2[]="N2 ";
char N3[]="N3 ";
char N4[]="N4 ";
char N5[]="N5 ";
char* TD[6];
int main ( int argc, char *argv[] )
{
// FN is a pointer to an array of chars
// BN is the same
//TL is an array of pointers (that each point to an array of chars)
//TL[1] is thus a pointer to an array of chars
//TL is the same structure as Argv
//TD is the same structure as Argv (but built up from parts)
// but is spread out across the globals and the main func.
// thus less easy to read and understand then TL.
//TL[i], TD[i], and BN are initially allocated significantly larger than FN
// to remove the worry of overruns.
//copy "a1 \0" into the space held by "c1 "
strcpy(BN,TL[1]); //works
//copy "BBBB\0" into the space held by "c1 "
strcpy(BN,FN); //works
TD[0]=N0;
TD[1]=N1;
TD[2]=N2;
TD[3]=N3;
TD[4]=N4;
TD[5]=N5;
//copy "BBBB\0" into the space held by "a1 "
strcpy(TD[1],FN); //works
//copy "BBBB\0" into the space held by "a1 "
//strcpy(TL[1],FN); //dies
}
Your char pointers point to string literals. Those are not writable. Even though their type is char* for historical reasons, you should always treat them as char const *.
Either malloc space for your char buffers, or use an array of arrays.
As the link posted by dasblinkenlight in comments above,
char * p = "xyz"; is different from
char p[] = "xyz";
The first is immutable, second is mutable.
Why do I get a segmentation fault when writing to a string initialized with "char *s" but not "char s[]"?
This question already has answers here:
Why do I get a segmentation fault when writing to a "char *s" initialized with a string literal, but not "char s[]"?
(19 answers)
Closed 9 years ago.
#include <stdio.h>
#include <conio.h>
void test(char *p)
{
p = p + 1;
*p = 'a';
}
int main()
{
char *str = "Hello";
test(str);
printf("%s", str);
getch();
return 0;
}
When I run this code it gives segmentation error ? why is this happening. The const theory is not clear to me... whereas if I declare str as char str[], it does the job. Are they not both basically the same things ?
str is pointing to a string literal, you are attempting to modify the string literal in the function test on this line:
*p = 'a';
It is undefined behavior to attempt to modify a string literal. You can alternatively, make a copy of the string literal into a array as follows:
char str[] = "Hello";
now it is perfectly ok to modify str. From the draft C99 standard, under section 6.4.5 String literals paragraph 6:
It is unspecified whether these arrays are distinct provided their elements have the
appropriate values. If the program attempts to modify such an array, the behavior is
undefined.
*p = 'a';
The problem is the above statement tries to modify the read only segment. String literal "Hello" resides in read only segment and can not be modified.
char str[] = "Hello";
The above statement copies Hello to str character array and the array contents can be modified.
This question already has answers here:
Access violation when using strcpy?
(8 answers)
Closed 9 years ago.
#include <stdio.h>
char *strcpy_r(char* s, char* t);
int main()
{
char *s = {"Bob"};
char *t = {"Billy"};
char *ptr;
ptr = strcpy_r(s, t);
printf("%s\n", ptr);
return 0;
}
char* strcpy_r(char* s, char* t)
{
if((*s = *t) != '\0')
strcpy_r(s + 1, t + 1);
return s;
}
I'm just doing this for practice, but when I compiled it. I got a seg fault from main. Could someone tell me what might've caused this seg fault?
Congratulations, you have invoked undefined behavior twice within one line.
First, you can't modify the contents of a string literal. So strcpy()ing onto "foo" is wrong.
Two, even if you could: you're copying a string to a buffer that is shorter than the string. This is UB again.
You are trying to modify a constant string. This is wrong! Chances of segfault live when you modify a constant string.
Instead do this:
char s[10] = "Bob";
char t[10] = "Billy";
char *ptr;
You can't overwrite the memory that's used to hold a quoted string. That'll segfault instantly.
String literals are constant, i.e. they cant change. You're also trying to copy a longer string into a shorter string, which will write beyond the bounds of the destination string.
Both of these problems leads to undefined behavior which can cause a crash.
To solve the first problem, you have to use an array for the destination string. To solve the other problem, you have to make sure the destination array is at least as large as the source string (including its terminating '\0').
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why do I get a segmentation fault when writing to a string?
Here is a small function, was testing something so wrote it. Here i tried to increment a character value of the string literal when i tried doing so i got a segmentation fault. Can you please tell what i am doing wrong here
#include <stdio.h>
int input_string(char *str)
{
printf("%s\n", str);
printf("%c\n", *str);
printf("%c\n", (*str)++); // I get a segmentation fault here, cant i increment the value like this ?
}
void main()
{
char *str = "andrew";
input_string(str);
}
What this char *str = "andrew"; does is create a pointer to a string that MAY be located on .text (where the executable code resides) and trying to modify it is undefined behavior.
Change it for this:
char str[] = "andrew";
It will make a copy of the string in a stack allocated buffer that you can safely modify.
This:
char *str = "andrew";
means what str points to a constant string literal. You will get undefined behavior if you try to change it.
If you want to perform string manipulation, define a character array.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why do I get a segmentation fault when writing to a string?
I'm experiencing a strange issue with my C code. I'm trying to split string using strtok function, but I get access violation exception. Here's my code:
char *token;
char *line = "LINE TO BE SEPARATED";
char *search = " ";
token = strtok(line, search); <-- this code causes crash
However, if I change char *line to char line[], everything works as expected and I don't get any error.
Anyone can explain why I get that (strange for me) behavior with strtok? I thought char* and char[] was the same and exact type.
UPDATE
I'm using MSVC 2012 compiler.
strtok() modifies the string that it parses. If you use:
char* line = "...";
then a string literal is being modified, which is undefined behaviour. When you use:
char[] line = "...";
then a copy of the string literal is being modified.
When assigning "LINE TO BE SEPARATED" to char *line, you make line point to an constant string written in the program executable. You are not allowed to modify it. You should declare those kind of variable as const char *.
When declared as char[], your string is declared on the stack of your function. Thus, you are able to modify it.
char *s = "any string"
is a definition of pointer which point to string or array of char(s). in the above example s is pointing to a constant string
char s[] = "any string"
is a definition of array of char(s). in the above example s is an array of char(s) which contains the charcters {'a','n','y',' ','s','t','r,'i','n','g','\0'}
strtock changes the content of your input string. it replaces the delimators in your string by the '\0' (null).
So, you can not use strtok with constant strings like this:
char *s="any string"
you can use strtok with dynamic memory or static memory like:
char *s = malloc(20 * sizeof(char)); //dynamic allocation for string
strcpy(s,"any string");
char s[20] = "any string"; //static allocation for string
char s[] = "any string"; //static allocation for string
To answer your question: char* and char[] are not same type?
This:
char *line = "LINE TO BE SEPARATED";
Is a string literal defined in read only memory. You can't change this string.
This, however:
char line[] = "LINE TO BE SEPARATED";
Is now a character array (the quoted text was copied into the array) placed on the stack. You are allowed to modify the characters in this array.
So they are both character arrays, but placed in different parts of memory.