-1

my code shows the problem this works

   char str[] = "asdf=1=2=3"; // this works
   printf("type:  %s\n", typename(str)); // prints 'pointer to char'
   char *token = strtok(str, "=");
   printf("%s\n", token);

this works not , why ?

   char *str2 = "asdf=1=2=3"; // this wont work
   printf("type:  %s\n", typename(str2)); // prints 'pointer to char'
   printf("%s\n", str2);
   char *token2 = strtok(str2, "="); // segmentation fault
   printf("%s", token2); 

edit: this is the typename macro

#define typename(x) _Generic((x),        /* Get the name of a type */             \
                                                                                  \
        _Bool: "_Bool",                  unsigned char: "unsigned char",          \
         char: "char",                     signed char: "signed char",            \
    short int: "short int",         unsigned short int: "unsigned short int",     \
          int: "int",                     unsigned int: "unsigned int",           \
     long int: "long int",           unsigned long int: "unsigned long int",      \
long long int: "long long int", unsigned long long int: "unsigned long long int", \
        float: "float",                         double: "double",                 \
  long double: "long double",                   char *: "pointer to char",        \
       void *: "pointer to void",                int *: "pointer to int",         \
      default: "other")
Jonas Frey
  • 65
  • 6
  • You did not post the `typename` macro or function... it should be modified to distinguish *array of char* and *pointer to char* , which `str` is not. – chqrlie Jan 30 '22 at 17:02

1 Answers1

0

the reason is the following

   char * pointer_to_readonly_memory_string = "asdf";
   char pointer_to_memory_on_the_stack[] = "asdf";

   // pointer_to_readonly_memory_string[0] = 'b'; // segmentation fault
   pointer_to_memory_on_the_stack[0] = 'b';

   printf(" pointer_to_readonly_memory_string: %s\n", pointer_to_readonly_memory_string);
   printf(" pointer_to_memory_on_the_stack: %s\n", pointer_to_memory_on_the_stack);
char * varname = "asdf";

when you use the asteriks * to initialize a string and assign a value with = the string in the double quotes "asdf" will place the string literal "asdf" in the read-only parts of the memory, and making varname a pointer to that, this makes any writing operation on this memory illegal.

char * varname = "asdf";

when you use square brackets [] and assign a value with = then the it puts the literal string in read-only memory , plus it copies the string to newly allocated memory on the stack. which means the memory will be modifiable. so you can do this : varname[0] = 'b';

Jonas Frey
  • 65
  • 6