This is a perfectly valid program except:
- not declaring 
p as volatile and 
- declaring 
argv as char *. 
And yes, free() needs to be called after longjmp() if the memory has been allocated before longjmp().
Since it's guaranteed that the return value of setjmp will be 0 on direct execution, we can be sure that memory will be allocated via case 0.
And, if a local variable needs to be changed after setjmp() and before calling longjmp then you need to declare it as volatile to ask compiler to not to optimize and store in registers but to store/load from stack only.
Why? Because when longjmp loads the saved environment it loads program counter, stack pointer and values in registers saved at the time of direct setjmp() call. If compiler optimizes and stores the variable in register after the setjmp() call then longjmp can't access that value since what it has is register values at the time of setjmp call. So we ask compiler to not to save in registers but to save/load from stack only. And since longjmp has stack pointer we get the latest values of accessible variables from the stack.
Updated code:
#include <setjmp.h>
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
    jmp_buf jmpbuf;
    volatile int *p;
    switch (setjmp(jmpbuf)) {
        case 0:
            p = malloc(10 * sizeof(int));
            printf("p = %p\n", (void *)p);
            longjmp(jmpbuf, 1);
            break;
        default:
            printf("p = %p\n", (void *)p);
            free((void *)p);
    }
    return 0;
}