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?
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.
optarg points an element in argv. If you can guarantee that argv isn't going away or getting touched by any other parts of the code, you should be good. Since argv is typically around from the start of main to the end of the program, you can safely cache these pointers.
But treat the optarg value as const char*. That is, don't try to do anything with this memory other than reference it or copy the original string. Attempting to do something like strcat on a pointer is unsafe at best.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With