Code in patched Cygwin for calculating path to command interpreter
You're allocating too much memory:

unsigned int total = nchars + 1 + sizeof cmdname + 1;


You only need 1 terminating null at the end of the string.  This is already accounted for in the size of cmdname (since you declare it as a string initialized []).  You can simply allocate:

unsigned int total = nchars + 1 + sizeof cmdname;


Or, if you add the "\" onto cmdname you could do:

char cmdname[] = "\\cmd.exe";
unsigned int total = nchars + sizeof cmdname;