segmentation fault when swapping pointer values while reversing a string [duplicate] - c

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 am trying to reverse a string. I take two pointers , one pointing to the start of the string and other at the end of the string . And then I swap the values of the pointers.
int main()
{
char *string = "stack overflow";
int len = strlen(string);
char *end;
char tmp; //temporary variable to swap values
//pointer pointing at the end of the string
end = string+len-1;
printf(" value of start and end %c %c", *string , *end); //correct values printed
while(string<end)
{
tmp = *string;
*string = *end; //segmentation fault
*end = tmp;
*string++;
*end--;
}
return 0;
}

char *string = "stack overflow";
This creates a read-only string literal. Modifying it is undefined behavior. Use an array instead:
char string[] = "stack overflow";

Related

trying copy character from pointer to string [duplicate]

This question already has an answer here:
String literals: pointer vs. char array
(1 answer)
Closed 2 months ago.
I am trying to reverse string using pointer (ref source). in function
string_reverse
Bus Error happened at this line when copying character from char pointer end to start char pointer :
*start = *end;
I tried LLDB in VS code. .
Can some one explain why there is bus error happened at below line?
*start = *end
Full code below:
#include <stdio.h>
#include <string.h>
void string_reverse(char* str)
{
int len = strlen(str);
char temp;
char *end = str;
char *start = str;
/* Move end pointer to the last character */
for (int j = 0; j < len-1; j++)
{
end++;
}
for(int i = 0; i< len/2;i++ )
{
temp = *start;
*start = *end;
*end = temp;
/* update pointer positions */
start++;
end--;
}
}
int main( void )
{
char *str = "test string";
printf("Original string is %s\n", str);
string_reverse(str);
printf("Reverse string is %s\n", str);
return 0;
}
Actual result: Bus Error happened at line
*start = *end;
Expected output:
Reverse string is gnirts tset
The error happens because
char * str = "...";
mean you have a pointer to a string literal. It's a constant string that you can not modify.
When you change it to
char str[] = "...";
as chux-reinstate-monica mentioned, str will be char array with the length of your string, and you can modify it without any error.

compiler does not allow me to edit the passed string [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)
Closed 5 years ago.
I looked around and I could not find a solution of my problems in other question. For some reason, then I get segmentation fault when I run my program and it seems to be because i am changing the give string. I tried passing a pointer to a char pointer and edit that, but to no avail.
what I get:
before: juanpablo
Segmentation fault (core dumped)
My code:
void rm_char(char* word, int pos){
printf("before: %s\n", word);
int len = strlen(word);
int i;
i = pos;
while(word[i+1] != '\0'){
word[i] = word[i+1];
i++;
}
word[i] = '\0';
printf("after: %s\n", word);
}
int main(void){
rm_char("juanpablo", 2);
}
From the C Standard (6.4.5 String literals)
7 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.
To escape the error you could call the function like
char s[] = "juanpablo";
rm_char( s, 2 );
Take into account that it is better to use type size_t instead of the type int for the second parameter and the variable len declared like
int len = strlen(word);
is not used in the function.
The function should be declared like
char * rm_char(char* word, size_t pos);
Here is a demonstrative program
#include <stdio.h>
#include <string.h>
char * rm_char(char *word, size_t pos)
{
size_t n = strlen( word );
if ( pos < n )
{
//memmove( word + pos, word + pos + 1, n - pos );
do
{
word[pos] = word[pos+1];
} while ( word[pos++] );
}
return word;
}
int main(void)
{
char word[] = "juanpablo";
puts( word );
puts( rm_char( word, 2 ) );
return 0;
}
Its output is
juanpablo
junpablo

passing a char* as argument breaks program whereas char[] does not [duplicate]

This question already has answers here:
What is the difference between char s[] and char *s?
(14 answers)
Definitive List of Common Reasons for Segmentation Faults
(1 answer)
Closed 5 years ago.
I have the following code to split strings by tokens:
char **strToWordArray(char *str, const char *delimiter)
{
char **words;
int nwords = 1;
words = malloc(sizeof(*words) * (nwords + 1));
int w = 0;
int len = strlen(delimiter);
words[w++] = str;
while (*str)
{
if (strncmp(str, delimiter, len) == 0)
{
for (int i = 0; i < len; i++)
{
*(str++) = 0;
}
if (*str != 0) {
nwords++;
char **tmp = realloc(words, sizeof(*words) * (nwords + 1));
words = tmp;
words[w++] = str;
} else {
str--;
}
}
str++;
}
words[w] = NULL;
return words;
}
If I do this:
char str[] = "abc/def/foo/bar";
char **words=strToWordArray(str,"/");
then the program works just fine but if I do this:
char *str = "abc/def/foo/bar";
char **words=strToWordArray(str,"/");
then I get a segmentation fault.
Why is that? The program expects a char* as an argument then why does a char* argument crash the program?
Because the function contains:
*(str++) = 0;
which modifies the string that was passed to it. When you do:
char *str = "abc/def/foo/bar";
str points to a read-only string literal. See the section titled Attempting to modify a string literal in this question:
Definitive List of Common Reasons for Segmentation Faults

Reverse a string of any length using pointers in C [duplicate]

This question already has answers here:
How do you reverse a string in place in C or C++?
(21 answers)
How to read unlimited characters in C
(3 answers)
Closed 9 years ago.
I was just browsing through some interview questions and found this code to reverse a string using pointers. But I see that here they have defined char string[100] which limits the string length. I am not so good at C. How do I modify the same to make it a string of any length?
#include<stdio.h>
int string_length(char*);
void reverse(char*);
main()
{
char string[100];
printf("Enter a string\n");
gets(string);
reverse(string);
printf("Reverse of entered string is \"%s\".\n", string);
return 0;
}
void reverse(char *string)
{
int length, c;
char *begin, *end, temp;
length = string_length(string);
begin = string;
end = string;
for ( c = 0 ; c < ( length - 1 ) ; c++ )
end++;
for ( c = 0 ; c < length/2 ; c++ )
{
temp = *end;
*end = *begin;
*begin = temp;
begin++;
end--;
}
}
int string_length(char *pointer)
{
int c = 0;
while( *(pointer+c) != '\0' )
c++;
return c;
}
Instead of static array use dynamic memory allocation: char *tab = malloc(n * sizeof(char)) where n is some variable representing desired length.
You can use malloc() for this purpose if you want the size to be decided/inputted by the user at runtime.
malloc()
Dynamic memory allocation is the solution..
Take a pointer to the string and allocate the memory dynamically.. this allocates at run time..
This will solve your problem..
char *str;
str = (char*)malloc(n *sizeof(char));
NOTE: typecasting is optional in C and 'n' here is the required length.(can be user input).

C reversing a String [duplicate]

This question already has answers here:
Segmentation fault occurring when modifying a string using pointers?
(8 answers)
Closed 9 years ago.
help me.. why this C program doesnt reverse the string ?
it crashes... but when i use a character array the code seems to work fine..but the moment i use a pointer to a string..its giving goosebumps...help me solve this..
#include<stdio.h>
#include<conio.h>
#include<string.h>
int main(){
char *String="gokul";
char *Begin =String;
char *End = String + strlen(String) - 1;
char TempChar = '\0';
while (Begin < End)
{
TempChar = *Begin;
*Begin = *End;
*End = TempChar;
Begin++;
End--;
}
puts(String);
}
The problem is that String is pointing to a string literal, which is in read-only memory. You can still use a pointer for String, but it has to point to memory that can be modified.
char gokul[] = "gokul";
char *String = gokul;
Edit to address some minor issues.
There is no need to include the non-standard header conio.h in your program.
Your code does not handle the case where String is NULL.
Your loop is technically incorrect if String is an empty string, since End would point before the string.
main() should return a value, since it is declared to do so. 0 indicates success. Newer C compilers will know that the latest C Standard allows a program to hit the end of main() without return to mean to implicitly return a 0 for you.
#include<stdio.h>
#include<string.h>
int main(){
char gokul[] = "gokul";
char *String=gokul;
if (String && *String) {
char *Begin =String;
char *End = String + strlen(String) - 1;
char TempChar = '\0';
while (Begin < End)
{
TempChar = *Begin;
*Begin = *End;
*End = TempChar;
Begin++;
End--;
}
puts(String);
}
return 0;
}

Resources