You get the segmentation fault because you are using uninitialized pointers.
In other words: *(args+i) is uninitialized.
Let's look at your memory:
char **args = malloc(argc * sizeof(char *));
This will give a local variable args that points to a dynamic allocated memory area consisting of argc pointers to char. Looks like this:

But the argc pointers to char are uninitialized (i.e. malloc doesn't initialized anything) so the real picture is:

That is - the argc pointers to char may point anywhere.
So when you do 
strcpy(*(args+i), argv[i+1]);
       ^^^^^^^^^
       Read uninitialized pointer
you read the i'th uninitialized pointer and copy the string at argv[i+1] to that location. In other words - to a location that we can't know where is and most like doesn't belong to your program. This is likely to result in a seg fault.
So before you copy anything you want those char-pointers to point to some chars. Like:

So basically you need to do additional malloc.
Now one problem is: How many chars do you need to malloc?
Well, you can't know until you know the length of the input strings. So you need to put the malloc inside the loop. Like:
int main (int argc, char * argv[]) {
    char **args = malloc(argc * sizeof(char *));
    for (int i = 0; i < argc - 1; ++i) {
        *(args+i) = malloc(strlen(argv[i+1]) + 1);  // Allocate memory
        strcpy(*(args+i), argv[i+1]);
    }
}
Note:
- You don't need to write - sizeof(char)as it is always 1
 
- You have to add 1 to the string length of the input string in order to reserve memory for the string termination. 
- You should always check that - mallocdoesn't return NULL
 
- Instead of - *(args+i)you can use the more readable form- args[i]
 
So after a real execution the picture could be:
