Your c_str_2 is a local variable. When it goes out of scope, its destructor (Drop impl) is run and the underlying buffer is deallocated, meaning that you ultimately write a dangling pointer to the out parameter.
If you want to transfer ownership to a (necessarily manually-managed) raw pointer, then use CString::into_raw() instead. Playground
Also note that when you have a char ** out parameter, then you are likely not supposed to strcpy() onto the inner pointer. If there were a pre-allocated buffer, then it would be sufficient to pass a char * and strcpy()/memcpy() into it. Instead, it is likely that there is no such pre-allocated buffer and you are supposed to fill in the buffer pointer itself with a newly-allocated pointer (which is my example above does).