1

I am a little bit confused about pointer-of-pointer-const-var-string-char ;) Her's my code:

char* str_get_var(char *string,char delim)
{
        char    *found,
                *found2,
                *teststring;

printf("var string: %s\t",string);
teststring=strdup(string);
printf(" ---- var teststring: %s\n",teststring);

string=strdup(teststring);

found = strsep(&teststring,&delim);
printf("teststring \t var found: %s\n",found);
found2 = strsep(&string,&delim);
printf("string \t\t var found2: %s\n",found2);

return found;
}


int main(int argc, char *argv[])
{
char *message;
char trenner;
char *gefun;

message="ehzg=1";
trenner = '=';

printf("Start\n");
gefun=str_get_var(message,trenner);
printf("Ende\n");
return(0);
}

The programm produces the following output:

Start
var string: ehzg=1       ---- var teststring: ehzg=1
teststring       var found: ehzg
string           var found2: ehzg
Ende

As you might see from the code I would say the strdup to teststring is not needed as I would expect I can use the *string directly. However, as soon as I comment the following line I am getting a SegFault:

\\string=strdup(teststring);

Her's the output when commented out:

Start
var string: ehzg=1       ---- var teststring: ehzg=1
teststring       var found: ehzg
Speicherzugriffsfehler

So my question(s): How can I use *string directly for strsep? Why do I get a segfault when not doing strdup with the same content?

(BTW: Coding on Raspbian, if important).

Thanks! /knebb

Christian
  • 169
  • 8
  • Why is it read-only? It is a pointer, how can I create a read-only pointer? And when it is read-only why can `strdup`overwrite it? – Christian Dec 15 '20 at 14:48
  • 2
    Because that's how C works. String literals cannot be written to. – Robert Harvey Dec 15 '20 at 14:50
  • To explain why this is the case, if you define the same string twice and check the string addresses you will probably find that they both have the same address. It is called string pooling and saves memory obviously. https://stackoverflow.com/questions/11399682/c-optimisation-of-string-literals – Sven Nilsson Dec 15 '20 at 14:57
  • I do not really get it here, sorry. Can you give me an example how to do without duplicating the strings? – Christian Dec 15 '20 at 15:01
  • 3
    Does this answer your question? [Why do I get a segmentation fault when writing to a "char \*s" initialized with a string literal, but not "char s\[\]"?](https://stackoverflow.com/questions/164194/why-do-i-get-a-segmentation-fault-when-writing-to-a-char-s-initialized-with-a) – Krishna Kanth Yenumula Dec 15 '20 at 15:02
  • 2
    Also the pointer is not read only, it is the DATA that it points to that is read only. Hence the name is const char *, while the read only pointer is a char * const. – Sven Nilsson Dec 15 '20 at 15:02
  • 1
    This is also wrong and causes undefined behaviour: `strsep(&string,&delim);` `delim` is a single character but `strsep` expects to get a proper C string, i.e. a nul-terminated sequence of characters. – Gerhardh Dec 15 '20 at 15:09
  • @KrishnaKanthYenumula: Thanks, the link helped a little bit. Ok, got it about the fact strings are treated as literals. Is there a way I can prevent this? @user3121023 Yeah, well. I am unsure how to use `strchr` either... ;) – Christian Dec 15 '20 at 15:10
  • 1
    The link provided by Krishna Kanth Yenumula addresses the difference between `char*` and `char[]`. That should give you some hints how to avoid read-only literals: Use an array instead. – Gerhardh Dec 15 '20 at 15:11
  • Ok, got it so far. I solved the issue by working around literals by this assignement: `message=malloc(sizeof("ehzg=1")); strcpy(message,"ehzg=1");` Thus, I can easily use the strings as expected. – Christian Dec 15 '20 at 15:19

1 Answers1

1

strchr could be used to find an = in the literal string.

#include <stdio.h>
#include <string.h>
char* str_get_var(char *string,char delim)
{
    char    *found2 = NULL;

    printf("var string: %s\t",string);

    found2 = strchr ( string, delim);
    if ( NULL != found2) {
        printf ( "string \t\t var found2: %s\n", found2);
    }

    return found2;
}

int main(int argc, char *argv[])
{
    char *message = "ehzg=1";
    char trenner = '=';
    char *gefun = NULL;

    printf ( "Start\n");
    gefun = str_get_var ( message, trenner);
    printf ( "Ende\n");
    if ( NULL != gefun) {
        printf ( "%.*s\n", (int)( gefun - message), message);
        printf ( "%s\n", gefun);
    }
    return(0);
}
user3121023
  • 8,181
  • 5
  • 18
  • 16