4

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.

2
  • What do you intend to do with send_args()? I am not sure, if your array is correctly initialized and it can hold all the values. I think the compiler might optimize the last two NULL away and you might write to unreferenced memory. Commented Mar 11, 2013 at 12:02
  • No, the compiler cannot optimize array elements away for exactly this reason: the size of the array is a relevant part of the program's data. Commented Mar 11, 2013 at 12:07

5 Answers 5

4

I see nothing wrong with the first example.

Sign up to request clarification or add additional context in comments.

3 Comments

I think the OP calls free because he calls strdup, which does calls malloc.
strdup does an implicit malloc.
free because I do strdup, which is allocate memory to char pointer. Thanks
1

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); 

Comments

0

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

Comments

0

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.

Comments

-1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.