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 want to replace a word in a string. Here is the code
char text[] = "This is a list of lists";
char *find = "list";
char* pos = NULL;
pos = strstr(text,find);
strncpy(pos,"test",4)
This works fine but
char *text = "This is a list of lists";
char *find = "list";
char* pos = NULL;
pos = strstr(text,find);
strncpy(pos,"test",4)
This gives a segmentation fault.
In the first example "text" is an array and the data is just copied at that location. In the 2nd one "text" is a pointer. What is issue?
The difference between
char text[] = "This is a list of lists"; // 1
and
char *text = "This is a list of lists"; // 2
is that, in (1), text is a non-constant array of characters; where as in (2), text points to a string literal, and string literals are are constant. You can't modify constant objects, which you're trying in (2). What you're doing in (2) in actually undefined behaviour.
The problem is the string in the second example is a string literal, which must remain constant. When you try to write on that string you are writing to read-only memory, which (depending on the operating system) is not allowed.
Related
This question already has answers here:
Pointer to Integer Array versus Double Pointer to Integer
(3 answers)
Is an array name a pointer?
(8 answers)
Why should I always enable compiler warnings?
(20 answers)
Closed 3 years ago.
The following code will segfault.
char* input = "12.34"; //< this is only to simplify the example.
char buffer[30] = { 0 };
memcpy(buffer, input, strlen(input));
char* part1 = strsep(&buffer, ".");
The following code will not.
char* input = "12.34"; //< this is only to simplify the example.
char buffer[30] = { 0 };
memcpy(buffer, input, strlen(input));
char* ptr = buffer; //< Only diff.
char* part1 = strsep(&ptr , ".");
When passed by reference (&) as a function argument, why does the difference between char** and char*[30] matter?
If you look at the man for strsep, it needs the double pointer because it tries to assign the pointer.
"char *strsep(char **stringp, const char *delim);
...
and *stringp is updated to point past the token"
Basically if you have an array, you can't just tell the head of the array to be in a new place. You can however make a pointer to any element in that array and then change the value of the pointer (thereby making it point to a different element if you so wish).
This question already has answers here:
Crash or "segmentation fault" when data is copied/scanned/read to an uninitialized pointer
(5 answers)
Closed 6 years ago.
I'm trying out the following code:
int main()
{
char *yo = "yo";
char *whaddup = NULL;
strcpy(whaddup,yo);
}
and I get a segfault. Complete C noob here - other places say I should initialize whaddup as an array. Why can't I pass in a pointer to null?
Just any strcpy documentation will tell you that the destination string should be a char array large enough to hold the string and the NUL terminator.
So what you need is something like
char* yo = "yo";
char* whaddup = malloc(strlen(yo)+1);
strcpy(whaddup, yo);
Or alternatively you could use strdup function which does this for you, but it's not standard as it's POSIX only.
You have to either declare whaddup as a character array or ideally allocate space for it with malloc.
int main()
{
char *yo = "yo";
char *whaddup = malloc(sizeof(char) * 8); // buffer for 8 characters
strcpy(whaddup,yo);
}
By initializing whaddup to NULL you are not giving it any space in memory, so even copying one character into it will result in a segmentation fault.
You can pass in a pointer to null, but you can not copy string from pointer to null.
The function char* strcpy(char* dest, const char* src) is copy string from address src to address dest, your dest is null.
This question already has answers here:
Modifying String Literal [duplicate]
(4 answers)
Closed 8 years ago.
I wanna split a string by '/' and change char '/' to '/0' in the string, so I wrote a function like this:
void parse_query(char* str){
char* p = str;
char** r = (char**)malloc(sizeof(char*)*5);
int i = 0;
r[i++] = p;
while(p=strchr(p,'/')){
*p = '/0';
p++;
r[i++] = p;
}
}
When I ran the program like below:
char* s = "a/b";
parse_query(s);
the segmentation fault occurred at this line:
*p = '/0';
Can anyone give me a suggestion?
When I ran the program like below:
char* s = "a/b";
So you are modifying the string literal "a/b", which is undefined behaviour. If you want to modify it, then use an array like this:
char s[] = "a/b";
parse_query(s);
In addition, you should do (as noted by AntonH):
*p = '\0';
or
*p = 0;
to terminate the string. '/0' is the different from '\0'.
Replace:
*p = '/0';
which is not actually one character, but two, with:
*p = '\0';
Which is replacing the value pointed to by p with a value of zero. Which is what I believe you want.
Apart from the fact that it should be '\0', I think the segmentation fault stems from the fact that the string "a/b" is a literal, and these are generally stored in read-only memory. This means you probably can't write to that memory, and if you try, you get a segmentation fault.
Make a copy of the literal string into a writeable buffer and try it on that. I bet it works then.
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?
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.