The problem lies in the function. It receives double *d_ptr. This means that d_ptr is a pointer to a double. But when you do:
d_ptr = new double;
this reassigns the pointer d_ptr a new address, without affecting the external pointer passed to the function.
What we want to do is assign the external pointer a new address. This means that when we do d_ptr = new double; we want d_ptr to be a reference to the external pointer. Then, by assigning d_ptr a new address, we assign the external pointer a new address. The correct way for the function to receive a pointer is:
void initializer(double *&d_ptr)
This means that the function has a variable d_ptr that is a reference to a pointer of type double. One character fixes everything:
#include <iostream>
void initializer(double *&d_ptr)
{
    d_ptr = new double;
}
int main(int argc, char **argv)
{
    double *my_d;
    initializer(my_d);
    *my_d = 2;
    std::cout << *my_d << std::endl;
    delete my_d;
}