The downside of having NULL mean free() is that, when no tidy-up is needed (e.g. the "void*" is in fact a simple int, cast to void*), it's necessary to write a no-op destroy.  Given that free() is actually a valid thing to pass as destroy, I'd prefer to have callers explicitly pass free, when it's the right destructor, and reserve NULL for "no tidy-up is needed" (which is a natural thing for it to mean, in any case).