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.
Related
This question already has answers here:
What is the difference between char s[] and char *s?
(14 answers)
Closed 1 year ago.
Good day,
I have a function ft_strupcase which takes in a char*, upper-cases it, and returns the parameter. The issue arose during the testing, namely using the function in a main. The following program results in a segmentation fault:
int main()
{
char *hey = "hEy";
printf("%s\n", ft_strupcase(hey));
}
whereas this variation doesn't:
int main()
{
char hey[] = "hEy";
printf("%s\n", ft_strupcase(hey));
}
Isn't *str and str[] the same? Doesn't str[i] = *(str + i)? Why do I encounter a segfault then?
int main()
{
char *hey = "hEy";
printf("%s\n", ft_strupcase(hey));
}
In this code, hey points to a string literal, which is a constant. Then ft_strupcase modifies the thing you pass it a pointer to. So this code attempts to modify a constant.
You can't modify a constant. That's what it means for something to be constant.
int main()
{
char hey[] = "hEy";
printf("%s\n", ft_strupcase(hey));
}
Here, hey is an array of characters, initialized from a constant. The array is modifiable since the array entries are not constants.
If you have int i = 3;, you can modify i, but you can't modify the 3. The first code tries to modify the thing on the right side of the = by passing a function that modifies the thing pointed to a pointer to it. The second code modifies the thing on the left side of the =, which is perfectly legal.
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:
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:
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?
Why do I get a segmentation fault when I try to modify a string constant?
I was trying to run the following two codes and I am getting a segmentation fault with file2.c but with file1.c I am not getting any fault. Can somebody explain what is the difference between the following codes :
file1.c
#include <stdio.h>
int main()
{
int i;
char string[11] = {"HelloThere"};
string[10] = '\0';
for(i =0;i<5;i++)
{
string[i] = 'a';
}
printf("%s\n",string);
}
and :
file2.c
#include <stdio.h>
int main()
{
int i;
char * string;
string = "HelloThere";
for(i =0;i<5;i++)
{
string[i] = 'a';
}
printf("%s",string);
}
This is because the assignment
char string[11] = {"HelloThere"};
copies the string constant into a writable memory, while
char * string = "HelloThere";
leaves it in the read-only memory. While it is absolutely OK to write to the writable memory (duh!) writing to read-only memory is undefined behavior, and may trigger a crash.
Note that you do not need to specify the size of your string explicitly, unless you want to allocate more memory than is required for your string literal:
char string[] = {"HelloThere"}; // <<== The size is empty
string = "HelloThere";
then
string[i] = 'a';
is wrong - you're trying to modify a string literal, which you can't. This results in undefined behavior, so anything can happen, including crashes.
However,
char sring[11] = "HelloThere";
creates an auto array (copying the contents of the string in it beforehands) and that's writable, it's allowed to modify their elements.