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 byorig_path_var
. - In the 2nd line
strdup()
is called to make a duplicate of this string. The waystrdup()
does this is by callingmalloc()
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 ofchar *
pointers. There isnb_colons 1
pointers in the array. - Then in the 2nd line the 0th element of
array
is initilized topath_var
(remember it is not not a string literal, but a copy of one). - In the 3rd line, the
current_colon
th element ofarray
is set topath_var j 1
. If you don't understand pointer arithmetic, this just means it assigns the address of thej 1
th char ofpath_var
toarray[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.