Alocação dinâmica de memória e de vetores

Galera, é sabido que em C, para alocar memória dinamicamente utilizamos a função malloc();
Até aí tudo bem, sei como alocar e trabalhar com memória dinâmica.

Mas faço-lhes uma pergunta, como é que o malloc() sabe quando é para alocar um vetor ou uma variável comum?

Seguindo a lógica:
malloc(1) // aloca 1 byte de memória
malloc(4) // aloca 4 bytes de memória (equivalente a um INT).
malloc(8) // aloca 8 bytes de memória

Suponhamos que eu vá alocar memória para um vetor de inteiros, poderia fazer por ex:
int pInt;
pInt = (int) malloc(10
sizeof(int)); // aloca memória para um vetor de inteiros de tamanho 10

Sabendo-se que um inteiro ocupa 4 bytes isso seria equivalente a fazer isso
pInt = (int) malloc(40);

Então, eu gostaria de saber como é que o malloc() sabe quando ele deve alocar um único bloco de tamanho X ou um conjunto de blocos para formar um vetor?

Ele não sabe nem precisa saber, ele aloca um “bloco” (informalmente falando) de memoria e a linguagem trata aquilo como quiser.

PS: Este código esta errado

    pInt = (int) malloc(10*sizeof(int)); 

deveria ser

    pInt = (int*) malloc(10*sizeof(int)); 

É um problema conceitual seu, um array não são varias coisas separadas, ele é armazenado como algo contínuo na memoria.

Escrevi bem rápido, não atentem-se a erros bobos de sintaxe.

Minha dúvida ainda não foi sanada.

É um problema conceitual seu, um array não são varias coisas separadas, ele é armazenado como algo contínuo na memoria.

Como assim? O que entendo por array, é que sejam blocos diferentes, porém colocados em sequência. Até por que, é necessário armazenar uma informação diferente em cada posição.

A pergunta permanece, como ele determina se aquele espaço alocado será usado como um array ou como um único bloco?

Por ex: malloc(8);

Poderia ser um único bloco: [ bloco8bytes ]
Poderia ser um bloco segmentado (array): [ [bloco4bytes] [bloco4bytes] ] total 8 bytes

Como ele diferencia essa forma de tratar o bloco? Por que se o bloco é único, penso eu que ao tratá-lo como vetor, não “andaria” num conjunto de espaços específicos para um array…

No geral um array é um unico “bloco” de memoria continuo, e em C você pode tratar cada pedaço dele como contendo um valor diferente. Por isso falei que é questão conceitual, o que você entende por array não é bem como as coisas funcionam. O que funciona dessa forma usando pedaços de memoria desconexos são outras estruturas como listas encadeadas.

Como já falei, o malloc() não precisa saber como tu vai usar a memoria que você alocou. E no caso o C vai subdividir a área alocada e tratar como uma posição de seu array.

Interessante… então é um ÚNICO bloco, no entanto, segmentado? Ou é errônio fazer essa afirmação?

Isso ainda não entrou na minha cabeça:
int* ptrInt = (int*) malloc(8);

Significa que posso tratar o endereço apontado por ptrInt tanto quanto array ou quanto único espaço?

O C vai acessar os valores dessa forma, não é segmentado de verdade.

Quando você diz

int *a = (int*) malloc(10 * sizeof(int));

Ele vai alocar memoria o suficiente para caberem 10 inteiros (10 * sizeof(int)) e armazenar o endereço dessa memoria no ponteiro a.

Pro C tanto faz se a aponta para a memoria de um único inteiro, vários, uma struct, etc. Isso só diz pro compilador pra ele tratar o que está naquela posição como um inteiro.

Quando você faz

a[2] = 1;

Ele vai pegar o endereço que está na variável a, incrementar o valor obtido de acordo com o tamanho do tipo apontado, no caso int, e salvar nesse endereço o valor 1.

É o mesmo que fazer

*(a + 2) = 1;

Note que o compilador sabe que a aponta para ints, então incrementa o endereço em 2 * sizeof(int) automaticamente.

Da uma olhada em tutoriais sobre ponteiros e arrays, que devem esclarecer mais, por exemplo:
https://www.ime.usp.br/~pf/algoritmos/aulas/pont.html
https://pt.wikibooks.org/wiki/Programar_em_C/Ponteiros#Ponteiros_e_vetores