Q: Tamanho da alocação de structs Quando declaro uma variável normal, de tipo int por exemplo, o compilador vai lá e, dependendo da arquitetura, separa 4 bytes. 
struct exemplo{
  int x;
  int b;
};

int main(){
   struct exemplo exemplo;
}

Quando declarei a variável exemplo na main o compilador aloca na stack tudo que está na struct exemplo. O certo não seria na variável exemplo alocar o tamanho da struct, que nesse caso nao seria 8 bytes?
E no caso de alocação dinâmica de memória, quando aloco um tipo int ela aloca 4 bytes de endereço, mas quando aloco uma struct são alocadas todas as variáveis da struct. Não teria que ser apenas o espaço da struct no ponteiro?

A: O tamanho de alocação de uma estrutura não é algo tão simples, existe a questão do alinhamento. Dependendo do compilador, das diretivas, do código e da plataforma que estiver rodando pode ser diferente mas há uma chance razoável que seja 8 bytes mesmo, só não conte com isto como se fosse certo. Isto pode ser descoberto pelo próprio código.
#include <iostream>
using namespace std;

struct Exemplo { int x; int b; };

int main() {
    Exemplo exemplo;
    cout << "Tamanho de exemplo: " << sizeof(exemplo) << endl;
    cout << "Valor de exemplo.x: " << exemplo.x << endl;
    cout << "Valor de exemplo.b: " << exemplo.b << endl;
    Exemplo *exemplo2 = new Exemplo;
    cout << "Tamanho de exemplo2: " << sizeof(exemplo2) << endl;
    cout << "Tamanho do objeto apontado por exemplo2: " << sizeof(*exemplo2) << endl;
    cout << "Valor de exemplo2 (o ponteiro): " << exemplo2 << endl;
    cout << "Valor de exemplo2->x: " << exemplo2->x << endl;
    cout << "Valor de exemplo2->b: " << exemplo2->b << endl;
    cout << "Tamanho de exemplo2.x: " << sizeof(exemplo2->x) << endl;
}

Veja funcionando no ideone. E no repl.it. Também coloquei no GitHub para referência futura.
A alocação dinâmica aloca a memória necessária para objeto que pretende alocar. Não importa se é na stack ou no heap, o tamanho deve ser o mesmo. No caso vai alocar espaço para um objeto, no seu exemplo ele teria 8 bytes e a variável vai receber o ponteiro para este objeto. O tamanho do ponteiro é fixo para a aplicação, todos ponteiros possuem o mesmo tamanho, o que varia é o tamanho do objeto que ele aponta. Ponteiro e o objeto que ele aponta são coisas distintas que possuem uma relação eventual. No caso o objeto que seria apontado deve ter 8 bytes, afinal seria a mesma estrutura.
Em um exemplo simples o objeto estaria no heap e o ponteiro alocado na variável estaria na stack. Mas nada impede que o ponteiro esteja no heap também basta o código preferir colocar lá por algum motivo.
Se quiser entender mais sobre ponteiro, tem uma pergunta sobre o assunto aqui no site.
