Home > Software design >  Is String Literal in C really not modifiable?
Is String Literal in C really not modifiable?

Time:09-12

As far as I know, a string literal can't be modified for example:

char* a = "abc";
a[0] = 'c';

That would not work since string literal is read-only. I can only modify it if:

char a[] = "abc";
a[0] = 'c';

However, in this post, Parse $PATH variable and save the directory names into an array of strings, the first answer modified a string literal at these two places:

path_var[j]='\0';
array[current_colon] = path_var j 1;

I'm not very familiar with C so any explanation would be appreciated.

CodePudding user response:

In the example

char* a = "abc";

the token "abc" produces a literal object in the program image, and denotes an expression which yields that object's address.

In the example

char a[] = "abc";

The token "abc" is serves as an array initializer, and doesn't denote a literal object. It is equivalent to:

char a[] = { 'a', 'b', 'c', 0 };

The individual character values of "abc" are literal data is recorded somewhere and somehow in the program image, but they are not accessible as a string literal object.

The array a isn't a literal, needless to say. Modifying a doesn't constitute modifying a literal, because it isn't one.

CodePudding user response:

Code blocks from the post you linked:

const char *orig_path_var = getenv("PATH"); 
char *path_var = strdup(orig_path_var ? orig_path_var : "");
const char **array;
array = malloc((nb_colons 1) * sizeof(*array));
array[0] = path_var;
array[current_colon] = path_var j 1;

First block:

  • In the 1st line getenv() returns a pointer to a string literal which is pointed to by orig_path_var.
  • In the 2nd line strdup() is called to make a duplicate of this string. The way strdup() does this is by calling malloc() and allocating memory for the size of the string 1 and then copying the string into the memory.
  • Since malloc() is used, the string is stored on the heap, this allows us to edit the string and modify it.

Second block:

  • In the 1st line we can see that array points to a an array of char * pointers. There is nb_colons 1 pointers in the array.
  • Then in the 2nd line the 0th element of array is initilized to path_var (remember it is not not a string literal, but a copy of one).
  • In the 3rd line, the current_colonth element of array is set to path_var j 1. If you don't understand pointer arithmetic, this just means it assigns the address of the j 1th char of path_var to array[current_colon].

As you can see, the code is not operating on const string literals like orig_path_var. Instead it uses a copy made with strdup(). This seems to be where your confusion stems from so take a look at this:

char *strdup(const char *s);

The strdup() function returns a pointer to a new string which is a duplicate of the string s. Memory for the new string is obtained with malloc(3), and can be freed with free(3).

The above text shows what strdup() does according to its man page.

It may also help to read the malloc() man page.

  • Related