0

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.

Barmar
  • 741,623
  • 53
  • 500
  • 612
Jon Forhan
  • 51
  • 1
  • 5
  • 1
    You have to check for `argc > 1` to ensure that `argv[1]` is non-null. At present, if you invoke your program with (e.g.) `./client`, you'll dereference the `NULL` pointer in `argv[1]` and segfault. You probably want: `if (argc > 1) parse_url(argv[1]);` – Craig Estey Dec 27 '22 at 22:27
  • 1
    In the second call in `main`, you are passing the address of a string _literal_. The actual string data will placed in R/O memory. So, doing `*p = 0;` is trying to write to protected, R/O memory. You'll get a protection exception (i.e. segfault) – Craig Estey Dec 27 '22 at 22:29
  • this helped a lot thank you. I now understand better after some further research using this knowledge and now understand why char arr[] = "http://blah" works but char *arr does not – Jon Forhan Dec 27 '22 at 22:38
  • 1
    You're welcome. Doing `char arr[] = "blah";` is [effectively] coded as: `char arr[5]; strcpy(arr,"blah");` for function scoped variables. – Craig Estey Dec 27 '22 at 23:05

1 Answers1

1

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);
}
Chris
  • 26,361
  • 5
  • 21
  • 42