Search code examples
cgetopt

Why does `optarg` not get overwritten?


I am new to getopt(3) and looked at some examples and came across this one.

These lines

  case 'c':
    cvalue = optarg;
    break;

looked weird to me because the content of optarg does not get copied into cvalue, they're just copying the pointer. But it works:

$ testopt -a -b -c foo
aflag = 1, bflag = 1, cvalue = foo

I expected optarg to be overwritten by a second call to getopt(), so I wrote my own program based on the example. Surprisingly, optarg does not get overwritten.

$ testopt -p -f me -t you
pflag = 1, from = me, to = you

Does this work consistently or should I always copy/duplicate?
Do I have to take care of free()ing everything returned in optarg?
Am I just getting lucky and the realloc() of optarg doesn't allocate to the same address?


Solution

  • From GNU manuals:

    If the option has an argument, getopt returns the argument by storing it in the variable optarg. You don’t ordinarily need to copy the optarg string, since it is a pointer into the original argv array, not into a static area that might be overwritten.

    That's why it doesn't need to copied or allocated. POSIX documentation requires this for optarg.