your arg1 is only size 4, but you're filling 5. Setting it to the proper size will fix your problem.
In your example that doesn't work, you're not printing until you pthread_join all the threads before you print them. You get corruption before you print when you join the fifth thread.
In your example that works, printing each result before joining to the next thread. This means you print before the fifth thread overwrites the first and second values (they are still being overwritten).
The reason it's the first two that are corrupted is because your ints are probably 32-bit and your pointers are probably 64-bit. So 1 extra pointer messes up the next two int positions.
As for returning complex results from a thread, pthread_exit returns a void * and pthread_join gets the value as an output parameter when it returns.
So if you need to return more than a primitive value, then put together a struct and return that.