BobAlmond
BobAlmond

Reputation: 459

c string pointer

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

Answers (5)

Jens
Jens

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

Zecharye Galitzky
Zecharye Galitzky

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

autistic
autistic

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

Abhineet
Abhineet

Reputation: 5389

Yes, they are perfectly valid. You need to be concerned about argc though because you are incrementing it one more than needed. It would not cause any "undesirable effects" as far as you are handling it correctly. You can check your code's example here

Upvotes: 0

Tony The Lion
Tony The Lion

Reputation: 63200

I see nothing wrong with the first example.

Upvotes: 4

Related Questions