There's a difference actually. In int b[10], b is a pointer constant (which means it can be used to modify its underlying data but it can't be changed to point to something else). The pointer in int (*b)[10] on the other hand can be changed to point to something else (as well as being able to change its underlying data of course). So the difference is that by saying that b is int (*b)[10]; you're hereby warning the next developer who sees your code that this b can point to something else somewhere in the code. That's why - obviously - don't do that except if you really intend to change what b is pointing to (otherwise you're just confusing who'll come after you).
Regarding your question, I checked using sizeof(b).
int (*b)[10] ==> sizeof(b) is 4 (which means no memory allocated - Option 2).
int b[10] ==> sizeof(b) is 40 (which means memory is allocated as expected - Option 1).
Look at this:
int (*b)[10];
int x[10];
b = &x;
This compiled. Change the size of the array to anything else. It'll not compile! This means that you're extremely correct :-D. Option 2 is written perfectly: This pointer can only point to an array of size 10 and nothing else.
[Added as per request of question owner]
What's the advantage of such a syntax? It's just a feature that's already there, and maybe it's useful for somebody. This is how I understand it (and please correct me if wrong): For example, you can say: string (*names_of_players_in_soccer_team)[11]; and the advantage is - obviously - restricting the array to be exactly 11 names to handle the application logic - the team must actually have exactly 11 names. This gives more readability for those who'll read your code, and emphasizes its correctness...