Bit of a tangent but, I don't know if a segfault should be considered a consequence of a "naive" implementation. Seems more like a consequence of a broken one.
A simple if (!A) goto err_free; would turn that segfault into a "Failed to parse file"
Also, it looks like qsort is implemented on his system as qsort_r:
http://osxr.org/glibc/source/stdlib/msort.c
Qsort_r appears to allocate O(n) extra memory when the data fits into 1/4 of physical memory. The comments suggest that the regular qsort is slower.