On Fri, 12 Aug 2005 11:12:49 +0900, "Roman Mashak" <mrv@tusur.ru>
wrote in comp.lang.c:
[color=blue]
> Hello, Peter!
> You wrote on Thu, 11 Aug 2005 21:53:38 +0100:
>
> ??>> What's wrong with the code like this (code in original post gets
> ??>> dumped at *sp++ = '\0' statement, so I decided to simplify a little):
> ??>> char *s = "abcde"; /* s point to 'a' character */
> ??>> *s = 'A'; /* replace 'a' with 'A' */
> ??>> s++; /* move pointer to 'b' */
> ??>>
> ??>> With best regards, Roman Mashak. E-mail:
mrv@tusur.ru
>
> PP> The problem here is trying to change the contents of a string literal.
> PP> For historical reasons, a type of "abcde" is char*, but it should be
> PP> treated as const char*. Changing the contents may "work" in some
> PP> implementations, but it is undefined. Imagine for example that all
> PP> string literals are stored in read-only memory. Trying to change them
> PP> may result in ignoring the change or in a run-time error on fussier
> PP> systems.
> Why is it not assumed that array (char s[] = "abcd") can be also allocated
> in ROM? My compiler has option allowing to treat string literals as writable
> (but it's not safe).
>
> Let's consider my original peice of code (here I put full version that
> crashes):
> -----
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> #include <netinet/in.h>
>
> struct host_info {
> char *host;
> int port;
> char *path;
> int is_ftp;
> char *user;
> };
>
> int parse_url(char *url, struct host_info *h)
> {
> char *cp, *sp, *up, *pp;
> char *host, *path;
>
> if (strncmp(url, "ftp://", 6) == 0) {
> host = url + 6;
> h->port = 21;
> h->host = url + 6;
> h->is_ftp = 1;
> } else {
> return -1;
> }
>
> sp = strchr(h->host, '/');
> if (sp) {
> *sp++ = '\0'; /* XXX */
> h->path = sp;
> } else
> h->path = strdup("");
>
> up = strrchr(host, '@');
> if (up != NULL) {
> h->user = h->host;
> *up++ = '\0';
> h->host = up;
> } else
> h->user = NULL;
>
> pp = h->host;
>
> cp = strchr(pp, ':');
> if (cp != NULL) {
> *cp++ = '\0';
> h->port = htons(atoi(cp));
> }
>
> return 0;
> }
>
> int main(void)
> {
> struct host_info *hh;
> hh = (struct host_info*)malloc(sizeof(struct host_info));
>
> int rc = parse_url("ftp://192.168.11.197/pub/test.txt", 0);[/color]
This is EXACTLY what three people just told you, and even posted links
to the specific FAQ page. You are passing a string literal to a
function that tries to modify it. Modifying a string literal is
undefined behavior. One possibility of undefined behavior is a
program "crash".
[color=blue]
> printf("return status rc=%d\n", rc);
>
> return 0;
> }
> -----
>
> As I stated earlier, segfault happens at XXX mark. If I'm right, then
> compiler treats that line as follows:
> 1) evaluate *sp
> 2) put '\0' into memory area pointed by 'sp'
> 3) increment pointer value
>
> So, I suspect crash occurs at second step.
> [OT]
> By the way, no faults happen while debug in GDB. Basically debuggers are
> supposed to reveal such kinds of problems.
> [/OT]
>
> With best regards, Roman Mashak. E-mail:
mrv@tusur.ru[/color]
At the top of main(), add this definition:
char url_to_parse [] = "ftp://192.168.11.197/pub/test.txt";
....then change the function call to:
int rc = parse_url(url_to_parse, 0);
--
Jack Klein
Home:
http://JK-Technology.Com
FAQs for
comp.lang.c
http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++
http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html