#Use what C++ provides
If you use the C++ versions of the headers:

    #include <cstdlib>
    #include <cstdio> // or better, <iostream>
    #include <cstring>

You'll get the names safely in the `std` namespace.  I see you include `<cmath>` but assume its names are exported to the global namespace - that's an error.  You can't depend on that happening (it's just an artefact of your implementation).

Also, prefer `new`/`delete` and `new[]/delete[]` over `malloc()`/`free()`.  You might be able to avoid memory management completely by using the standard containers; that's a Good Thing.

`std::max()` and `std::min()` are safer choices compared to your `maxd()` and `mind()` macros.

#Avoid I/O in parallel code
These prints may get interleaved in unpredictable ways:

    #pragma omp parallel for
    for (int i = 0; i < cur_root; i += 2)
      {
        fprintf (temp, "%lf %lf %lf\n",
                 roots[i], roots[i+1],
                 calculateDensityScalarFromDensity(min, max, densities[i / 2])); 
      }

You *might* do something like

    #pragma omp parallel for
    for (int i = 0; i < cur_root; i += 2)
      {
        auto density = calculateDensityScalarFromDensity(min, max, densities[i / 2])
    #pragma omp critical
        fprintf (temp, "%lf %lf %lf\n",
                 roots[i], roots[i+1],
                 density); 
      }