| Giorgos Keramidas 2006-07-03, 7:22 pm |
| On Mon, 03 Jul 2006 15:54:38 -0700 (PDT), Ian Zimmerman <nobrowser@gmail.com> wrote:
> thus http://www.opengroup.org/onlinepubs...s/dirname.html:
>
> Great, it's a MAY. How in the world do I know how to dispose with the
> result pointer? It can be the same as the argument (nothing seems to
> preclude that), a newly malloced one, or a static one.
Since dirname(3) may modify the storage passed to it through its
argument, it's not safe to assume that it can work correctly with data
that may be read-only (i.e. a `const char *' pointer). This means that
the following may not work correctly:
const char *foo = "/tmp/foo";
char *dname;
dname = dirname(foo);
Since dirname() is allowed to allocate storage internally and return a
pointer to that area, you will probably have to save the original
pointer and then compare it with the return value of dirname():
char foo[] = "/tmp/foo";
char *dname;
dname = dirname(foo);
if (dname == foo) {
...
} else {
....
}
But even this does not necessarily mean that you can free() the return
value of dirname() when it is not the same as the original, as it may be
just a static internal buffer of dirname() which is not obtained through
malloc().
These portability issues of dirname() usually force me to write my own
version, which has a more clean API:
char *xdirname(char *);
for which I know that the argument string is *NOT* modified at all, the
return value is a copy of the directory path of the argument, the return
value is obtained through malloc() and it is a responsibility of the
caller to free() the return value. This may or may not waste a bit more
memory than the original dirname(), but it is usually (for the programs
I write myself) far more easy to use without causing silly bugs 
|