See this example:
int *array = malloc (10 * sizeof(int))
Is there a way to free only the first 3 blocks?
Or to have an array with n
You can't free part of an array - you can only free() a pointer that you got from malloc() and when you do that, you'll free all of the allocation you asked for.
As far as negative or non-zero-based indices, you can do whatever you want with the pointer when you get it back from malloc(). For example:
int *array = malloc(10 * sizeof(int));
array -= 2;
Makes an array that has valid indices 2-11. For negative indices:
int *array = malloc(10 * sizeof(int));
array += 10;
Now you can access this array like array[-1], array[-4], etc.
Be sure not to access memory outside your array. This sort of funny business is usually frowned upon in C programs and by C programmers.