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 last month.
I'm parsing urls for web client in C on linux. I noticed something I don't understand. When taking in the url as a cli arg my code funtions fine, when hard coding it, it fails. I'm new to network C programming.
#include<stdio.h>
#include<string.h>
void parse_url(char* url) {
printf("url: %s\n", url);
char* p = strstr(url, "://");
if(p) {
*p = 0;
p += 3;
}
printf("url body: %s\n", p);
}
int main(int argc, char* argv[]) {
parse_url(argv[1]);
parse_url("http://github.com/");
}
when ran as
./client http://github.com/
the first one behaves as intended giving expected output of
url: http://github.com/
url body: github.com/
second hard coded string fails
url: http://github.com/
Segmentation fault (core dumped)
I am more used to C++ and am C noob so sorry if this is incompetence but I can't find an explanation any where, thank you.
The second calls involves a string literal, which cannot be modified, which you do when you use the following because p is a pointer into the string.
*p = 0;
Had you passed a pointer to a char array initialized with a string literal, you would not have this issue.
int main(int argc, char* argv[]) {
parse_url(argv[1]);
char url[] = "http://github.com/";
parse_url(url);
}
Related
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 2 years ago.
I have a simple C program as follows:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
void convertToUpperCase(char* sPtr);
int main(int argc, char** argv) {
char myString[] = "cHaRacTerS aND $32.95";
char* anotherString = "cHaRacTerS aND $32.95";
convertToUpperCase(myString); // THIS IS OK!
convertToUpperCase(anotherString); // THIS CAUSES RUNTIME ERROR
// (ie. build success but run fail)!
return (EXIT_SUCCESS);
}
void convertToUpperCase(char* sPtr) {
while (*sPtr != '\0') { // current character is not null (ie. end of string).
*sPtr = toupper(*sPtr); // turns valid characters into upper case
++sPtr; // point to next character within the string.
}
}
It seems like passing anotherString into the function that expects a char* is the problem. From my understanding, both myString and anotherString are char* in C.
It seems to me the problem is how they are defined. For myString I defined it as an array of characters with a null terminator at the end. For anotherString it is a character pointer to a string literal somewhere.
But I can't figure out why the way they are defined matters in this situation.
Thanks in advance :)
edit: used specific terms as suggested by answers.
Because when you declare a literal, it is read only.
char myString[] = "cHaRacTerS aND $32.95"; // readwrite memory
char* anotherString = "cHaRacTerS aND $32.95"; // placed in readonly memory
Edit: to clarify, it is not only read-only, it is UB to write to a string literal. Thanks for that comment, #chux-reinstate-monica
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 4 years ago.
I am a beginner programmer. I wrote the following code to copy the one string into other, using pointers.
But I am not getting the output. The compiler says segmentation fault.
I have gone over and over the program, but to no avail. I am not able to locate the fault, and how to fix it.
It would be hard to believe but I have been stuck for almost 2 hours now.
Any help is greatly appreciated.
#include<stdio.h>
char *copy(char*, char*);
int main() {
char *str1 = "avanti";
char *str2 = "ujj";
printf("%s\n", str1);
char *result = copy(str1, str2);
printf("%s", result);
}
char *copy(char *str1, char *str2){
int i=0;
while (*(str2+i) != '\0') {
*(str1+i) = *(str2+i);
i++;
}
*(str1+i) = '\0';
return str1;
}
"avanti" is a string constant, not a place you can copy to. You might change it to char str1[] = "avanti"; This is an array of characters that is initialized with the value of the string constant "avanti"
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 6 years ago.
I tried the following code with sprintf, but it crashes in some cases and works fine in the other. Could anyone explain it to me?
#include <stdio.h>
#include <stdlib.h>
int main()
{
//char *s = malloc(20); //works fine
//char *s = ""; //does not work, no matter what the initial value is
char s[20]; //works fine
sprintf(s, "%s", "hello world");
printf("%s",s);
return 0;
}
When you are doing this:
char *s = "";
or
char *s = "longer string";
You are creating a literal string which is possibly placed in read-only memory. So you cannot change it later.
If you try to do the following syntax:
char s[] = "...";
the array will be initialized with the literal string and you will be able to modify the original array later.
Suggested questions on site:
What is the difference between char s[] and char *s in C?
Why do I get a segmentation fault when writing to a string initialized with “char *s” but not “char s[]”?
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)
Segmentation fault (core dumped) in a simple C code
(3 answers)
Closed 8 years ago.
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char *Change(char *str,int start,int end)
{
if(start==end || start>end){
return str;
}
else{
char temp=str[start];
str[start]=str[end];
str[end]=temp;
return(Change(str,start++,end--));
}
return str;
}
char *Reverse(char *str)
{
int length=strlen(str);
return(Change(str,0,length-1));
}
int main()
{
printf("%s\n",Reverse("program"));
return 0;
}
I am trying to write a recursive function to reverse a string,but it comes the linking error.Please help.I had tried so many times and searched in the Internet,but it can't help.
I guess the most probably place causing the problem is in function Change,but I can't solve with it.
You're passing a string literal (which is a const char*) to Reverse(), since you can't modify a string literal, your program generates a segmentation fault.
You'll either need to pass a modifiable string to Reverse():
char myStr[] = "program";
printf("%s\n",Reverse(myStr));
Or you can make a copy of the input string in Reverse():
char *Reverse(const char *str)
{
int length=strlen(str);
char* temp = malloc(length);
strcpy(temp, str);
return(Change(temp,0,length-1));
}
In that case, you'll need to free the string returned by Reverse():
char* reverseStr = Reverse("program");
printf("%s\n", reverseStr );
free(reverseStr);
Also in change(), start++ end end-- will return the value before they are incremented, you need to use either ++start or simply start+1 since you won't use those variables anymore:
return(Change(str,start+1,end-1));
Simple explanation: You can't modify a string literal. One more thing is that the statement
return(Change(temp,0,length-1));
will cause compilation error because neither temp is defined in the function Reverse nor it is globally defined.
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 have written a code . this looks as follows .
#include<stdio.h>
#include<string.h>
int do_print2(char *q[]);
int main()
{
char *p[]={"pointervaule","NAM", "JAM", "CALM"};
do_print2(p);
return 1;
}
int do_print2(char *p[])
{
printf("this is print1 char *p \n");
strcat(p[0],"added");
printf("%s\n", (p[0]));
return 1;
}
after compilation, i am trying to run it, i am getting segmentation fault. help me in learning what is the reason for that error. thank in advance.
In your code: strcat(p[0],"added"); try to write on read only memory that is illegal in C. Because p[0] points to a constant string.
Not p is pointer to char array, but not 2-dimensional char array.
Read: Difference between char* str[] and char str[][] and how both stores in memory? an answer with diagrams and code examples, to understand it better.
The OS says that the C strings are in the read section of the object (i.e. protected from writing).
Due to historical reasons "bla bla" is really a const char * const data type, but is allowed to get away in the C compilers eyes some teenage interdependencies. But the headmaster (OS) is less forgiving and expels the running of such code in the corridors. (how many metaphors in that statement).
You can't write to read only memory, better way to do this:
#include<stdio.h>
#include<string.h>
int do_print2(char q[][20]);
int main()
{
char p[4][20] = {{0}, {0}, {0}, {0}};
strcat(p[0],"pointervaule");
strcat(p[1],"NAM");
strcat(p[2],"JAM");
strcat(p[3],"CALM");
do_print2(p);
return 1;
}
int do_print2(char p[][20])
{
printf("this is print1 char *p \n");
strcat(p[0],"added");
printf("%s\n", (p[0]));
return 1;
}