Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
typedef struct nolista {
int dado;
int d;
struct nolista *prox;
}no;
feito essa estrutura para lista encadeada eu criei uma função para localizar o endereço de memoria de cada variável criada.
void funcao() {
struct nolista d;
struct nolista d1;
struct nolista d2;
struct nolista d3;
struct nolista d4;
printf("%p", &d);
printf("\n%p", &d1);
printf("\n%p", &d2);
printf("\n%p", &d3);
printf("\n%p", &d4);
}
o resultado foi o seguinte:
0022FF30
0022FF20
0022FF10
0022FF00
0022FEF0
A minha duvida: Se eu declarar 2 inteiros, e cada inteiro tem 4 bytes vai ser a mesma coisa que se eu declarar 3 inteiros. No total vai ficar 16 bytes.
4 bytes de um inteiro + 4 bytes de outro inteiro + um ponteiro da estrutura 4+4=8, no final, fica: 4+4+8=16.
Sabendo que um inteiro pode ser também 2 bytes, então ele divide 2 bytes para cada inteiro? tipo se eu declarar 3 inteiros na estrutura.
typedef struct nolista {
int dado;
int d;
int o;
struct nolista *prox;
}no;
4 bytes de um inteiro + 2 bytes de outro inteiro + 2 bytes de outro inteiro + um ponteiro da estrutura 4+2+2=8, no final, fica: 4+2+2+8=16. Eu acho que ele faz isso automaticamente para economizar a memoria.
Alguém pode me explicar como funciona isso? E porque os endereços esta na ordem decrescente?
Obrigado
então deve ter ocorrido o padding bits ;D ... Porque eu peguei o sizeof de struct nolista quando eu tinha declarado apenas dois inteiros e um ponteiro da própria struct e ele retornou 12. Já com 3 inteiro foi retornado 16. O endereço hexadecimal continuou o mesmo para ambos, acredito que teve o padding bits no primeiro caso então.
A forma como a implementação (leia 'compilador' ou 'interpretador') organiza os objetos em memória não é importante, a não ser quando se trata de 'partes' de uma mesma array. Mesmo neste caso, não se costuma usar os valores numéricos, e sabe-se apenas (e isto é suficiente) que os elementos têm posições consecutivas e adjacentes, e podem ser acessados usando aritmética de ponteiros.
O tamanho de cada tipo de dados depende da implementação. A linguagem define valores limitantes inferior e superior para os valores máximo e mínimo (respectivamente) de cada tipo. Exemplo: int deve ser capaz de representar o máximo valor mínimo INT_MIN, que deve ser menor ou igual a -32767. Analogamente, há INT_MAX, que deve ser maior ou igual a 32767. Estes limites estão em limits.h.
Quanto ao conceito de byte, até nisso há flexibilidade. Em C, um byte é o tamanho de um char. A quantidade de bits que compõem um byte é maior ou igual a 8. O tamanho dos outros tipos de dados é sempre um múltiplo do tamanho de um char. Portanto, em C, um byte pode ter mais de 8 bits. Em implementações de PDPs e alguns IBMs, bytes tinham 9 bits e ints, 36 (4 bytes). Portanto, quando sizeof te diz quantos bytes seu operando tem, não assuma que há esta quantidade x 8 bits.
Quanto à posição adjacente dos seus objetos em memória, há uma footnote relevante na seção 6.5.10:
Two objects may be adjacent in memory because they are adjacent elements of a larger array or
adjacent members of a structure with no padding between them, or because the implementation chose
to place them so, even though they are unrelated.
O que não muda é o tamanho de um tipo em uma mesma implementação (ou seja, todos os chars têm o mesmo tamanho, assim como todos os ints, floats, etc).
O tamanho de uma struct pode ser maior que a soma dos tamanhos dos seus elementos, pois pode haver padding bits, que não são contabilizados por sizeof.