Este array tem um tamanho de 1, mas eu posso inicializá-lo com esses valores, então eu posso até mesmo definir mais valores depois de instanciar o array e ele ainda funciona. Eu não entendo o porquê.
int array[1] = {12,2,12,12,12,31};
printf("%d\n",array[1]);
printf("%d\n",array[0]);
array[1] = 1;
array[8] = 3;
printf("%d\n",array[1]);// 1 It works. Why?
printf("%d\n",array[8]);// 3 It works. Why?
Em C, arrays não têm verificação de limites incorporada. Acessar além dos limites declarados de um array não faz com que seu programa trave imediatamente. Em vez disso, é chamado de comportamento indefinido . Comportamento indefinido significa que o padrão não define o que deve acontecer, então o programa pode parecer "funcionar", ou pode travar ou corromper a memória.
Quando você faz isso:
array[1] = 1;
array[8] = 3;
Você está escrevendo em regiões de memória fora do espaço alocado para o array. O compilador não impede você de fazer isso, e se essas regiões de memória não forem críticas para a execução do seu programa (ou se você tiver sorte), seu programa pode parecer rodar normalmente. Mas isso é apenas sorte, e comportamento imprevisível pode acontecer a qualquer momento.
Como outros apontaram, seu compilador provavelmente emitirá avisos.
Para lhe dar uma resposta direta, o que está acontecendo é que você está definindo um símbolo associado ao nome do array "array" de um elemento, então o programa coloca os valores inicializadores começando pelo endereço &a[0] independentemente do tamanho do array associado.
O que significa que sizeof(array) ainda deve retornar 1 e qualquer operação de acesso a elementos de array em índice maior que 0 gerará avisos do compilador.
Provavelmente, se você definir outra variável int depois do array com um valor atribuído, o segundo elemento do inicializador do array será substituído na memória pelo anterior.
Arrays não existem realmente em C. Eles são apenas regiões do espaço de memória do seu processo. Sua variável aponta para o primeiro endereço, e a
a[n]
sintaxe está procurandon
posições depois dea
.O array não lembra qual é seu comprimento, nem impõe que você esteja acessando apenas a memória que ele possui. Você está apenas lendo/escrevendo em memória arbitrária após o fim.
Se essa for uma memória válida dentro do seu processo, você estaria sobrescrevendo alguns dos seus outros dados. Se não for, o SO matará seu processo com uma falha de segmentação (SIGSEGV).