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').
Related
This question already has answers here:
Crash or "segmentation fault" when data is copied/scanned/read to an uninitialized pointer
(5 answers)
Closed 4 years ago.
Here is a simple program that is a function which checks for the character 'a' within a string, then returns the character if found, and NULL if it is not found. I am not really sure if it is the function or the call of the function itself, here is the code.
#include <stdio.h>
char *find_char(char *str, char character);
int main(){
char *str;
printf("str\n");
scanf("%s", str);
printf("%c",*find_char(str,'a'));
return 0;
}
char *find_char(char *str, char character){
char *pstr = str;
while(*pstr!='\0' && *pstr!=character){
pstr++;}
if (*pstr!=character)
return NULL;
else
return pstr;
}
Your problem basically lies in these two lines, the first and third code line of your main function:
char *str; // Create pointer, pointing to ***arbitrary*** memory.
scanf("%s", str); // Write to that memory, undefined behaviour.
You need to create backing storage for the pointer so you have somewhere valid to write your input to.
A better idea would be to use a rock-solid input routine rather than relying on often-dodgy practices like writing to invalid memory, or allowing uncontrolled input into limited-size buffers. One such beast can be found here.
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:
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 am writing a code for squeeze(s1,s2) that deletes each character in string s1 that matches any character in string s2 and I get "Segmentation fault (core dumped)" when I try to run the program.
I believe the error comes from in how i call the function inside the main(). I am a beginner and I don't know how to call functions. Please help!
#include<stdio.h>
void squeezer(char s[], char c[]);
main()
{
squeezer("abcdefgabcdefgabcdefg", "abcd");
}
void squeezer(char s[], char c[])
{
int i,j,k,z;
for(k=0; c[k] != '\0'; k++) {
for(i=j=0;s[i] != '\0';i++) {
if (s[i] != c[k]) {
s[j++] = s[i];
}
s[j] = '\0';
}
}
for(z=0; z < j; z++)
printf("%c",s[z]);
}
You are passing string literal to your function and then trying to modify it. You can't modify a string literal. Modifying a string literal invokes undefined behavior. In such case you may get either expected or unexpected result You may get segmentation fault or program crash too.
You can change your main function as
int main(void)
{
char s1[] = "abcdefgabcdefgabcdefg";
char s2[] = "abcd";
squeezer(s1, s2);
}
Must read: comp.lang.c FAQ list ยท Question 1.32.
String literals are "constant", read-only. You cannot change them, and that is what squeezer() tries to do.
You're writing to string literals, which is undefined behaviour. If your compiler put them in read-only memory, then your program should segfault. Try making writable copies of your strings in main, like so:
int main(int argc, char** argv)
{
char s[] = "abcdefgabcdefgabcdefg";
char c[] = "abcd";
squeezer(s, c);
return 0;
}
Depending on the C compiler and operating system you are using, the string literal you pass to squeezer may be "read-only" -- i.e. immutable -- at run-time. This is the same mechanism meant to prevent modification of compiled code at run-time.
The fix is to allocte a character array large enough to hold s using malloc or declare a char s[80] in main or as a global variable and then use strcpy to copy your first string literal into s before passing it as the first argument to squeezer.
Alternatively, you could pass the allocated or declared array variable as a third argument to squeezer and copy the "squeezed" string into it. Or, if you want to make squeezer as robust as you can, allocate a result array with malloc in squeezer that is strlen(s) in size, use it to accumulate the "squeezed" letters, and then return the pointer to the allocted array from squeezer whose return type will have changed from void to char *.
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:
How to reverse a string in place in c using pointers?
I was trying to reverse a string using C.
A segmentation fault occurs. Any idea why?
Here's my code:
#include <stdio.h>
#include <string.h>
int main(void)
{
char *str1 = "abbd";
char *str2;
str2 = str2 + strlen(str1)-1;
while(*str1 != '\0')
*(str2--) = *(str1++);
printf("%s", str2);
return 0;
}
Nothing's properly allocated (allocate the proper length at declaration or malloc it) and you don't really move through the strings and check for the end of your condition as fitted (try str[i]). You have awaken the kraken.
Looks like you didn't allocate any space for str2, just made the pointer.
char *str2;
str2 = str2 + strlen(str1)-1;
You declared a pointer str2, but initialize its value to garbage. (str2 + ...)
Are you trying to do an in-place modification? That won't work for this code, the char *foo="bar"; format places the "bar" in a write-protected memory space on platforms that support it.
Are you trying to do an out-of-place modification? If so, you forgot to allocate that space.
You're not allocating memory for str2.
str2 = (char *)malloc(sizeof(char) * (strlen(str1) + 1));
I haven't tried it, but it seems like you're going to want to set str2 = str2 + strlen(str1), otherwise I think you'll run off the "front" of your str2 buffer as well.
I would recommend treating your strings as arrays, and let the compiler do the pointer arithmetic for you.