Why segmentation fault occurs in the following [duplicate] - c

This question already has answers here:
Modifying String Literal [duplicate]
(4 answers)
Closed 10 years ago.
I am trying to remove two consecutive duplicate elements from the string.I am getting segmentation fault in the line 16 .even the commented 17th line also get me the same error.
dont worry about my logic of my program.it may be wrong...but i am struck with this error..help me out...explain why i am getting this error
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *st="fvvbbyyr";
int i=0,j,len;
for(len=0;st[len]!='\0';len++);
for(i=0;i<len;i++)
{
if(st[i]==st[i+1])
{
for(j=i+2;j<len;j++)
{
*(st+j-2)=*(st+j);
//st[j-2]=st[j];
}
len = len-2;
i=-1;
}
}
return 0;
}

char *st = "fvvbbyyr";
st points to the anonymous string "fvvbbyyr", which can be located in read-only memory.
*(st+j-2) = *(st+j);
Attempting to modify such value leads to an undefined behavior.
A good habit is to declare the pointer as const char * because a string litteral behaves in this way.
const char *st = "fvvbbyyr";
Then your compiler should print some warnings/errors. Use rather an array:
char st[] = "fvvbbyyr";
BTW, the array subscripting operator [] may make your code more readable.
st[j - 2] = st[j];
Moreover you are accessing to st[i+1] == st[len] once in your loop.

Related

Why editing a * string in C results in a segmentation fault, but a [] one doesn't? [duplicate]

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.

Avoid Bus error: 10 during test cases [duplicate]

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)
Why is this string reversal C code causing a segmentation fault? [duplicate]
(8 answers)
Closed 4 years ago.
I'm attempting to remove duplicate characters from a string without using any additional buffer. The code works when I declare a single variable like this
char s[] = "aaabbb";
but not when I'm attempting to loop through a few test cases.
#include <stdio.h>
#include <string.h>
/* Design an algorithm and write code to remove the duplicate characters in a string
without using any additional buffer. NOTE: One or two additional variables are fine.
An extra copy of the array is not. */
void removeDuplicates(char s[]) {
// attempts to modify array in place without extra buffer
}
int main() {
char *s[4] = {"aaaa", "abcd", "ababab", "aaabbb"};
int i;
for (i = 0; i < 6; i++) {
removeDuplicates(s[i]);
}
return 0;
}
This returns Bus error: 10 because it's attempting to modify the string literal "aaaa" but I'm not sure how to overcome this while maintaining a nice setup for the test cases.
The s[i] are pointing to string literals, you need a 2-dimensinal char array like this:
char s[][7] = {"aaaa", "abcd", "ababab", "aaabbb"}
Also note that for a string of length n you need at least n+1 spaces because of the '\0'-termination."aaabbb"` has length 6, so it need at least 7 spaces.
Then you can do
int main() {
char s[][7] = {"aaaa", "abcd", "ababab", "aaabbb"};
size_t i;
for (i = 0; i < sizeof s / sizeof s[0]; i++) {
removeDuplicates(s[i]);
}
return 0;
}

Bad permissions for mapped region [duplicate]

This question already has answers here:
Why is this string reversal C code causing a segmentation fault? [duplicate]
(8 answers)
Closed 9 years ago.
I get an error when trying to run the following function:
char* reverseInPlace(char* src)
{
//no need to alloc or free memory
int i=0;
int size=mystrlen(src);
for(i=0;i<size;i++)
{
int j=size-i-1;
if(i<j)
{
char temp;
printf("Interchange start %d:%c with %d:%c",i,src[i],j,src[j]);
temp=src[i];
src[i]=src[j];//error occurs here
src[j]=temp;
printf("Interchange complete %d:%c and %d:%c",i,src[i],j,src[j]);
}
}
return src;
}
I call this code like this:
char* rev2=reverseInPlace("BeforeSunrise");
printf("The reversed string is %s\n",rev2);
The error looks like this:
Interchange start 0:B with 12:e
Process terminating with default action of signal 11 (SIGSEGV)
Bad permissions for mapped region at address 0x401165
Why does this error occur?
You are passing a constant string to your function.
String literals are of type char [N + 1] (where N is the length of the array) in C, but modifying them results in undefined behavior. Your compiler should have already issued a warning at that point.
If you wish to modify it then you have to create a copy:
char str[] = "BeforeSunrise";
char* rev2=reverseInPlace(str);
It's because you try to modify a string literal, which is a constant array, i.e. it's read-only.

Segmentation fault while using char * string but not with char string[11] [duplicate]

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.

strtok() - Segmentation Fault [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
strtok giving Segmentation Fault
I try to use strtok function to split string in many tokens but in this example it returns me a seg. fault error. Where i'm in wrong??
#include <stdio.h>
#include <string.h>
int main(int argc, char** argv){
int i=0;
char * string = "HI:HOW:ARE:YOU:?", *tmp;
while(1){
if(i==0) tmp=strtok(string,":");
else tmp=strtok(NULL,":");
if(tmp==NULL) break;
printf("%s\n",tmp);
i++;
}
return 1;
}
Change
char * string = "HI:HOW:ARE:YOU:?"
for
char string [] = "HI:HOW:ARE:YOU:?"
With char string [] you have an array, and char * you have a pointer. When you declare an array, it will request space to allocate the size of your string. The char * string creates a pointer that points to a literal string.
The problem with char *string it is that the point should not be changed because string literals are typically stored in read-only memory, thus causing undefined behavior 33
( for more detail read this https://www.securecoding.cert.org/confluence/display/seccode/STR30-C.+Do+not+attempt+to+modify+string+literals )
Therefore, since with strtok the contents of the string is modified and broken into smaller strings (tokens) you got problems.

Resources