Reputation: 459
I'm starting to learn C and I'm a little bit confuse with c string pointer.
int argc = 0;
const char *str[] = { "hello" , NULL, NULL };
str[argc++] = "nice!";
str[argc++] = "abc";
str[argc++] = "def"
send_args(argc, str);
//the prototype/header : int send_args(int argc, const char **args);
because send_args function doesn't modify the value of passed str, are those operation valid? because I don't want to do something like :
int i, argc = 0;
char *str[3];
str[argc++] = strdup("nice!");
str[argc++] = strdup("abc");
str[argc++] = strduo("def)"
send_args(argc, str);
for (i = 0; i< argc; i++)
if (str[i]) { free(str[i]); str[i]=NULL; }
Thanks in advance guys.
Upvotes: 4
Views: 676
Reputation: 72639
Yes, that's alright. The string literals are likely placed in the initialized data section (details are implementation defined) and there is no need (in fact, not even a possibility) to free literals.
The type of str
is compatible with the one required by send_args
, so all is fine.
Note that as written, str[]
is initialized with three elements and thus cannot hold four or more pointers. You could achieve the same effect with a declaration and initialization like
const char *str[3];
str[0] = "nice!";
str[1] = "abc";
str[2] = "def"
send_args(3, str);
Upvotes: 1
Reputation: 26
In this case they are valid, because the strings are stored statically at compile time and cannot be freed. Their pointer addresses also do not depend on the function you are in.
But if you would use a local char array for "nice!"
, it would not be valid, because the send_args cannot read local variables of other functions.
Upvotes: -1
Reputation: 15642
If you're asking about automatic storage duration, your str
array won't be destroyed until execution reaches the end of the block it was created within.
const char **fubar(void)
{
int argc = 0;
const char *str[] = { "hello" , NULL, NULL }; /* str is created here */
str[argc++] = "nice!";
str[argc++] = "abc";
str[argc++] = "def"
send_args(argc, str); /* the lifetime of str is still valid here */
return str; /* ... but str gets destroyed after this "return" statement */
}
int main(void) {
const char **fubared = fubar();
/* str has already been destroyed, and fubar's return value has been rendered garbage */
/* so using fubared would be a bad idea. */
return 0;
}
return
causes str to be destroyed, because execution has surpassed the end of the block it was created within, and the pointer being returned would point to garbage.
Upvotes: 0