Is this an optimal implementation of merge sort? I am taking an algorithm course and we are to implement merge sort that handles list of elements with even or odd number of elements and handles duplication, so I wrote this function:

void mergesort (int* list, int len)
{
        if(len == 1) return;
        int i = len/2, j = len-i;
        int list1[i], list2[j];
        for(int k=0;k&lt;i;k++)
        {
                list1[k]= list[k];
                list2[k]= list[i+k];
        }
        if(len%2!=0) list2[j-1] = list[len-1];
        mergesort(list1 , i);
        mergesort(list2 , j);
        int k=0,l=0;
        // k represent counter over elements in list1
        // l represent counter over elements in list2
        // k+l represent counte over total elements in list
         while(k+l!=len)
        {
                if(k==i)
                {
                        for(;l&lt;j;l++) list[k+l] = list2[l];
                        return;
                }
                else if (l==j)
                {
                        for(;k&lt;i;k++) list[k+l] = list1[k];
                }
                else if(list1[k]&lt;list2[l])
                {
                        list[k+l]=list1[k];
                        k++;
                }
                else if(list1[k]&gt;list2[l])
                {
                        list[k+l] = list2[l];
                        l++;
                }
                else
                {
                //handles dublication
                list[k+l] = list1[k];
                k++;
                list[k+l] = list[l];
                l++;
                }
        }
}


I have 2 questions:


How can I make this implementation more optimal (best possible performance)?
When handling arrays of large lengths (1000000), what causes a segmentation fault?


NOTE: I tried the function using array randomly generated of length 1000 and it worked.
Suspect that segmentation fault on large arrays occurs because the list1[] and list2[] ran out of space.  With the recursive calls, code is heavily using the stack space.  Use malloc() and free() for large arrays instead of VLA[]
Memory allocation could be reduced.  Via recursion, this takes > 2n (maybe 4n) memory space.  At worst it should be 2n.
Use size_t rather than int for a integer type that can handle all array indexes.

// void mergesort (int* list, int len)
void mergesort (int* list, size_t len)

Cope with 0 length.

// if(len == 1) return;
if(len &lt;= 1) return;