Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does `optarg` not get overwritten?

Tags:

c

getopt

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?

like image 261
Zauz Avatar asked Oct 24 '25 05:10

Zauz


2 Answers

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.

like image 117
P.P Avatar answered Oct 26 '25 18:10

P.P


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.

like image 44
selbie Avatar answered Oct 26 '25 17:10

selbie