Segmentation fault when reversing string in C [duplicate] - c

This question already has answers here:
Reverse a string in C solution segfaulting
(2 answers)
Closed 10 years ago.
I have the following code which its main purpose is reverse the characters of a string. So, for example, the string I love cats would be converted to stac evol I.
#include <string.h>
#include <stddef.h>
#include <stdio.h>
void reverseString(char *str)
{
int size = strlen(str);
char *end = str + size - 1;
char tmp;
while (end > str) {
tmp = *str;
*str = *end;
*end = tmp;
end--;
str++;
}
}
int main()
{
char *str = "Y U SEGMENTATION FAULT?";
reverseString(str);
}
When I run this, I get a segmentation fault, and I fail to see why. Also, another question I have is the time complexity (Big O) of this function. I believe it should be O(n/2), since I am not going through all the array but just the half of it. Am I right?

You are trying to modify a character literal, a string in read only data segment. Make a copy/duplicate of it on the heap with strdup, for example:
char *str = strdup("It's OK now");
Or make it a local array (place the string on the stack):
char[] str = "It's OK now";

Related

Cannot use strcpy with 2 string (segmentation fault) [duplicate]

This question already has answers here:
Crash or "segmentation fault" when data is copied/scanned/read to an uninitialized pointer
(5 answers)
Closed last year.
What's wrong with this code?:
int main(int argc, char ** argv) {
char strs[] = "What will be printed?";
char *str1;
char *str2;
strs[5] = '\0';
str1 = strs;
strcpy(str2, str1);
printf("%s\n", str2);
return 1;
}
I want it to print "What", instead i get segmentation fault.
I believe it has something to do with the strcpy(str2, str1);, but what is the explanation for that? The signature of strcpy is char* strcpy(char* destination, const char* source); and that's exactly what i did.
Could you explain that to me?
Your destination string is not initialized - it has no memory reserved for itself. An attempt to write to it causes invalid memory access (you're trying to overwrite something completely random and unplanned) and is followed by a segmentation fault.
One clean way to initialize a string is to define a global macro variable that just sets the largest size of strings you plan on using in your code,
#define MAXBUF 100
Then in your main you can simply write:
char str2[MAXBUF];
And your program will work. Alternative is to use dynamic memory allocation which you will likely learn about soon.
#include <stdio.h>
#include <string.h>
int main() {
char *src = "What will be printed?";
char dest[100];
int START = 0; // start of copy
int LENGTH = 5; // length of copy
// copies up to LENGTH characters from the string pointed to, by src to dest. In a case where the length of src is less than that of LENGTH, the remainder of dest will be padded with null bytes.
strncpy(dest, &src[START], LENGTH);
printf("%s\n", dest);
return 0;
}

gcc warning assignment makes pointer from integer without a cast [duplicate]

This question already has answers here:
Crash or "segmentation fault" when data is copied/scanned/read to an uninitialized pointer
(5 answers)
Closed 3 years ago.
I am trying to make all possible combinations of alphabets using a number. Input NUM given by user.
The combinatitions are created by splitting input numbers upto two digits. Input Obtained as char*
I am Using C. I am getting output as Segmenation fault (core dumped), guessing because of the warning.
substr is my own function.
sample input and output
input: 11112
output:
AAAAB
AAAL
AAKB
AKAB
AKL
KAAB
KAL
KKB
My CODE
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char* substr(char* str,int l,int n)
{
char* c;
int len = n-l;
while(l<n)
{
*c = *(str+l);
l++;
c++;
}
*c='\0';
return c-len;
}
int printAlpha(char* str, char* word)
{
char *sub;
char* ch;
int n = strlen(str);
if(n == 0)
{
printf("%s",word);
}
else
{
sub = substr(str,0,1);
int num = atoi(sub);
str = substr(str,1,n);
ch = 'A'+(num-1);
printAlpha(str, strcat(word, ch));
sub = substr(str,0,2);
num = atoi(sub);
if(strlen(str)>=2 && num <= 26)
{
str = substr(str,2,n);
ch = 'A'+(num-1);
printAlpha( str, strcat(word, ch) );
}
}
return 0;
}
int main()
{
char* str;
char* word = '\0';
scanf("%s",str);
printAlpha(str,word);
return 0;
}
thanks in advance.
As commenters have said you need to allocate memory in c dynamically.
In c if you need to store something like an array of characters you have 2 basic szenarios:
You know how many elements your array will contain before you compile then you can use
char word[numberOfLetters]
this will work as long as you dont need to store more letters, it becomes problematic in the other case
you dont know how big your array has to be before compiling
e.g when you are doing stuff with veriable lengths. imagine storing a user input into a char array. How should you make the array? if you make it 100 chars big and the user types 101 then you will get a segfault or loose everything he typed after the 100th char
you could also deal with this by making the array huge, but then with a short input youd be wasting a lot of memory and you still have the problem that if you need 1 char more than what you chose as size it wont work.
here is where you have to use dynamic memory allocation using functions like element_ptr* =malloc(numOfElements*sizeof(element)); to request memory during runtime.
what malloc does is it returns a pointer to the address, of the memory you requested
when you dont need the memory anymore you call free(element_ptr); this will free the memory again, otherwise it will stay blocked.
best you read up on malloc in the man pages

Segmentation fault on execution of a C program related to strings [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)
Difference between declared string and allocated string
(3 answers)
Closed 8 years ago.
I have the following code. I initialized 2 pointers, one at the beginning and another at the ending of a string. After every step, I increment the 1st pointer and decrement the second pointer. I copy the value of first pointer into the second if the value obtained by dereferencing 1st pointer is less than the value obtained by dereferencing 2nd pointer.
#include <stdio.h>
#include <string.h>
int main() {
char *word="aacdbc";
char *p=word;
char *q=word+(strlen(word)-1);
printf("\n%s\n",word);
int i;
for(i=1;i<=strlen(word)-1;++i) {
if(*p<*q) {
*q=*p;
}
++p;
--q;
}
printf("\n%s\n",word);
return 0;
}
But the code shows a "Segmentation fault error". In which line did I make a mistake?
String literals in C (and C++) are immutable. So your attempt to change the string literal pointed to by the variable word
char *word = "aacdbc";
has undefined behaviour.
Change the definition from a pointer to an array
char word[] = "aacdbc";
The program could look the following way
#include <stdio.h>
int main( void )
{
char word[] = "aacdbc";
char *p = word;
char *q = word+ + sizeof( worrd ) - 1;
printf( "\n%s\n", word );
while ( p < q && p < --q )
{
if ( *p < *q ) *q = *p;
++p;
}
printf( "\n%s\n", word );
return 0;
}
Because word is a pointer to a constant (read-only) characters sequence. In other words, you can't change the contents of a string literal.
If you want to change its contents, you should declare word as an array of chars:
char word[]="aacdbc";
With that small change, the segfault should disappear.

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.

Reverse C string - simple bug [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is it possible to modify a string of char in C?
#include <stdio.h>
void reverseStr(char *str);
main()
{
reverseStr("abcdef");
}
void reverseStr(char *str) {
char *tmp = str;
char curr;
while (*tmp != '\0') {
tmp++;
}
tmp--;
while (tmp > str) {
curr = *str;
*str = *tmp;
*tmp = curr;
str++;
tmp--;
}
}
When I run it, I get:
/usr/bin/runit/srun_c: line 12: 2809 Segmentation fault /tmp/run_c_executable
What on earth is going on? I'm practicing for an interview, I'm rusty in my C and wanted to practice something easy but can't for the life of me figure this out.
I've noticed the seg fault disappears when I comment out the *str = *tmp; line, and I don't see why that should cause a seg fault.
Help appreciated.
You can't modify constant strings. Use a char array instead:
char str[] = "abcdef";
reverseStr(str);
You can't modify string literals — they're stored in readonly memory.
Use:
char str[] = "abcdef";
reverseStr(str);
Your reversal function looks fine. But it is the way you are calling the function that is causing this crash. You are passing a string literal which are read-only to the function. And modifying a string literal is a undefined behavior, manifesting as crash in your case.
Change
reverseStr("abcdef");
to
char str[] = "abcdef";
reverseStr(str);
where you pass a character array to the function.

Resources