Q:

C - Value seems to pass to array element correctly but doesn't

Sorry I know that's a really badly worded question - I just couldn't think of a better way to say it.
I have asked this here as I cannot seem to word it correctly to find a solution my Googling.
Code explanation:

Separates file name 'echo' from file_name char array. file_name contains 'echo x y'
The loop starts at 'x' which is the previous file names length +1 (for the space).
The while loop loops until the next space is seen. The null char is to ensure the loop ends when the end of file_name is hit.
It assigns the value of file_name to arg_tmp until it hits a space then assigns this word / letter to the argv array
It then ++ the current_arg counter for the next arg

Hopefully this makes sense and there is enough code there to identify the problem.
MAX_FILE_NAME_LENGTH is 14
strlen(exec_name) = 4 so  the +1 makes it 5.
Length is 9.
Here is my code :
void
 setup_argv(const char *file_name, char *argv[], size_t argc, size_t length)
 {
   char exec_name[MAX_FILE_NAME_LENGTH];
   char arg_tmp[MAX_FILE_NAME_LENGTH]; // temp arg holder
   // get file name
   get_exec_name(file_name, exec_name);
   // add file name to argv
   argv[0] = exec_name;

   // get rest of args
   // +1 - start at first character of next arg
   int current_arg=1;
   for(size_t i = strlen(exec_name)+1; i < length; i++)
   {
     size_t j = 0;
     while(!(file_name[i] == NULL_CHAR || file_name[i] == SPACE))
     {
       arg_tmp[j] = file_name[i];
       printf("::WHILE::%s\n", arg_tmp);
       i++;
     }
     printf("::BOTH::%d %s\n", current_arg, arg_tmp);
     arg_tmp[++j] = NULL_CHAR;
     argv[current_arg] = arg_tmp;
     printf("::ARGV CUR ARG::%s\n", argv[current_arg]);
     printf("::ARGV::%s\n", argv[1]);
     printf("::CUR ARG::%d\n", current_arg);
     current_arg++;
     printf("::CUR ARG::%d\n", current_arg);
   }

   printf("::ARGV ALL::%s %s %s\n", argv[0], argv[1], argv[2]);
 }

Here is my output:
::WHILE::x
::BOTH::1 x
::ARGV CUR ARG::x
::ARGV::x
::CUR ARG::1
::CUR ARG::2
::WHILE::y
::BOTH::2 y
::ARGV CUR ARG::y
::ARGV::y
::CUR ARG::2
::CUR ARG::3
::ARGV ALL::echo y y

What should be printed in the last line is 'echo x y'.
I have used print statements to debug it and try to find where it goes wrong - but I can't seem to see it.
For some reason, it's printing and passing in y twice. 
Why is this? What am I doing wrong?
EDIT :  As I have now figured out - I cannot use malloc or strdup (unless I write my own functions for these). This is because I am doing an operating systems modules coursework.  Is there alternatives methods or should I look for written functions of these?

A:

The variable argv is an array of pointers, and you make all pointers in the loop point to the very same place, the first element of arg_temp.
This is even worse than you think, because when setup_argv returns, then the lifetime of arg_temp ends and it ceases to exist, leaving you with an array of stray and invalid pointers. Attempting to dereference them will lead to undefined behavior.
As a solution I suggest you use the common strdup function, or make up your own string-duplication function which allocates new memory for the strings.
Lastly, for a correct argv style array, you should terminate it with a null pointer.

