Why am I getting this error ? 
You are overwriting the destination pointer instead of assigning the value returned by malloc to the pointer pointed to by the destination pointer.
- Instead of *destination = (int*)malloc(sizeof(int) * 10)you should type**destination = malloc(sizeof(int) * 10).
- Instead of *destination[i] = iyou should type(**destination)[i] = i.
In C, the array subscript operator [] has a higher precedence than the indirection operator *. In addition to that, the former is left-to-right associative, while the latter is right-to-left associative.
In your case this means that you need to type (**destination)[i] = i; instead of **destination[i] = i, because otherwise the [i] will be evaluated before the ** and you end up indirecting a wild pointer (which will cause a segmentation fault extremely likely in the general and absolutely certainly in this case, since you are referencing a null pointer when i == 0).
How can this be fixed ?
The "just make it work" fix is the one I presented above.
However, that does not address the fundamental issue with your code, which is that it is unnecessarily complicated. Using a pointer to a pointer is very error-prone and should be avoided. Indeed, there is no need to use one at all in this case.
The following does exactly what you want without all the unnecessary complexity:
int* func_1()
{
   int* destination = malloc(sizeof(int) * 10);
   for (int i = 0; i < 10; ++i)
   {
      destination[i] = i;
   }
   return destination;
}
int main()
{
   int* pointer = func_1();
   free(pointer);
   return 0;
}
Please note that I wish to retain the values I have assigned to the dynamically allocated memory inside the function, once the function exits, and that's the reason due to which I have passed the address of the pointer to which I want to allocate memory dynamically.
As I demonstrated above, there is no reason to pass a pointer to the pointer to the function. Memory allocated with malloc is yours to use forever , you just need to keep track of it and release it with a call to free when you no longer need it. How you keep track of the memory doesn't matter - simply returning a pointer is enough in this case. Modifying pointer inside func_1 rather than catching the function's return value provides no additional benefit and only serves to make the code more complicated than it needs to be.
I get the impression that you are somewhat confused about pointers, so I recommend that you revise the subject. Here is a quite clear explanation regarding pointers that also covers pointers to pointeres (and pointers to pointers to pointers): How do pointers work in C?
Read more: