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(10sizeof(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?
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.
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.