Ir ao conteúdo

Posts recomendados

Postado

Oi pessoal tudo bem? seguinte, criei a seguinte estrutura:

typedef struct {
    int numero1;
    float numero2;
    char letra;
} DADOS;

Eu esperava que essa estrutura tivesse tamanho igual a 7 bytes (int = 2 bytes, float = 4 bytes, char 1 byte) porém quando mando imprimir sizeof(DADOS) a saída é 12! alguém saberia me explicar o por quê?

  • Curtir 1
Postado
2 minutos atrás, AnsiC disse:

Para Windows 32bits essa estrutura tem: 9 bytes.

char: 1 byte

int: 4 bytes

float: 4 bytes

to usando win64 aqui... quanto deveria dar?

Postado
15 minutos atrás, alecounter disse:

to usando win64 aqui... quanto deveria dar

Por padrão gcc compila em 32 bits independente do Windows 64, qual nome do seu compilador?

  • Curtir 2
Postado
agora, AnsiC disse:

Por padrão gcc compila em 32 bits independente do Windows, qual nome do seu compilador?

é o gcc mesmo. mas você disse que a soma deu 9B, mas quando eu faço sizeof(DADOS) a resposta é 12B... o que está consumindo esses 3B?

  • Curtir 1
Postado
2 minutos atrás, AnsiC disse:

Ps.: Faça sizeof para tipo é constante seus tamanhos.

eu fiz aqui...
sizeof(int)=4B
sizeof(float)=4B
sizeof(char)=1B

 

somatório = 9B. mas sizeof(DADOS)=12B != 9B... por que a diferença?

Postado
agora, AnsiC disse:

Bem, provavelmente está promovendo o inteiro char para int

então vou criar uma estrutura só de char's para ver se isso realmente está acontecendo, um momento

adicionado 1 minuto depois

criei aqui e está dando 3 bytes(criei uma estrutura com 3 char).

adicionado 2 minutos depois

engraçado que quando crio apenas uma estrutura com 1 char , o "peso" é 1B. agora se coloco um int na estrutura, passa a "pesar" 8B. porque isso?

  • Curtir 1
Postado
3 minutos atrás, alecounter disse:

então vou criar uma estrutura só de char's para ver se isso realmente está acontecendo, um momento

Essa promoção pode apenas ocorrer se houver um ou mais itens do tipo int, junto com número cuja a divisão por 4 de resto do tipo char.

adicionado 1 minuto depois

Exemplo:

typedef struct {
        char letra1;
        int letra0;
} Dados;

O resultado vai ser 8.

  • Curtir 2
Postado
5 minutos atrás, AnsiC disse:

Essa promoção pode apenas ocorrer se houver um ou mais itens do tipo int, junto com número cuja a divisão por 4 de resto do tipo char.

adicionado 1 minuto depois

Exemplo:


typedef struct {
        char letra1;
        int letra0;
} Dados;

O resultado vai ser 8.

por qual motivo isso acontece? e uma curiosidade, onde voce aprendeu C?

  • Curtir 1
Postado

Isso ocorre para otimizar o acesso a memória, e mais fácil calcular o tamanho do bloco de dados quando esse da salto de 1 em 1 ou de 2 em 2, ou de 4 em 4.

adicionado 1 minuto depois
2 minutos atrás, alecounter disse:

onde voce aprendeu C?

No curso de Física

  • Curtir 2
Postado
5 minutos atrás, AnsiC disse:

Isso ocorre para otimizar o acesso a memória, e mais fácil calcular o tamanho do bloco de dados quando esse da salto de 1 em 1 ou de 2 em 2, ou de 4 em 4.

adicionado 1 minuto depois

No curso de Física

acho que entendi, mas você aprendeu C no curso ou aprendeu usando algum livro? porque você sempre fala de regras, e no livro que estou usando não estou vendo nada disso

  • Curtir 1
Postado
2 minutos atrás, alecounter disse:

acho que entendi, mas você aprendeu C no curso ou aprendeu usando algum livro? porque você sempre fala de regras, e no livro que estou usando não estou vendo nada disso

Essas coisas existem apenas em livros velhos do tempo do ANSI C que você encontra nas bibliotecas ou em artigos na internet. Meu caso foi na biblioteca mesmo, a maioria é inglês.

 

Você pode pesquisar esses assunto, porém os melhores resultados vem de postes internacionais. Experientemente pesquisar: size of struct in C, ou sizeof dispensed more size struct

 

Coisas assim vai lhe ajudar nas dúvidas, e se não nos conte que nós ajudaremos.

adicionado 2 minutos depois

Lembrei de um: A Bíblia do C\C++ - ótimo livro.

adicionado 3 minutos depois

Esse foi traduzido, acho que você pode encontra na internet em pdf!

  • Curtir 2
Postado

Primeiro, vários dos tipos básicos do C tem um tamanho mínimo necessário, mas o tamanho real depende da implementação do compilador e do sistema onde está sendo usado.

 

Então, a norma define que o tipo int deve ter pelo menos 2 bytes de comprimento, mas na prática costuma ser implementado com 4 bytes em compiladores para computadores (mas um compilador para um sistema embarcado por exemplo poderia usar int com 2 bytes).

 

Para saber qual o tamanho de cada tipo cuja norma só define um tamanho mínimo basta testar cada um com sizeof no seu compilador, ou pesquisar na internet.

 

Então teoricamente sua struct teria 4 + 4 + 1 = 9 bytes.

 

 

Mas acontece que num sistema de 32 bits memória é dividida em blocos de 32 bits ou 4 bytes, então a memória é alocada em múltiplos de 4 bytes.

 

Então, sua struct precisa alocar 4 bytes para o int, 4 bytes para o float, e 4 bytes para o char (apesar do tipo char ter tamanho 1 byte), totalizando 12 bytes para a struct inteira.

 

Do último byte alocado apenas 1 byte será utilizado de fato, para armazenar o valor do tipo char, os outros 3 bytes não são utilizados. Mas note que poderia adicionar outras variáveis char, ou até uma variável short int, no fim da struct, e essas variáveis ocupariam e usariam esses bytes que foram alocados mas não foram utilizados, e o tamanho total da struct ficaria inalterado.

 

Isso também implica que a ordem dos itens na struct é importante, pois uma struct mal organizada pode aumentar muito o espaço ocupado pela struct.

 

Por exemplo:

//Essa struct mal organizada ocupa 16 bytes:
struct est{
    int a;
    char b;
    int c;
    short int d;
}

//Mas essa ocupa apenas 12 bytes:
struct est2{
    int a;
    int c;
    char b;
    short int d;
}

O problema na primeira struct é que 4 bytes são alocados para o char b, mas esse só usa 1 dos 4 bytes, e sobram 3 bytes, mas o int c ocupará 4 bytes, então não cabe nos 3 bytes que sobraram na alocação do char c, logo precisa ser alocado um novo grupo de 4 bytes para guardar o int c, e os 3 bytes não utilizados são desperdiçados.

 

Já na segunda struct o char b (1 byte) e o short int d (2 bytes) cabem juntos dentro de apenas 1 grupo de 4 bytes que foi alocado, ocupando 3 bytes, e apenas 1 byte fica sobrando não utilizado.

  • Curtir 3
  • Obrigado 1
Postado
4 minutos atrás, isrnick disse:

Mas acontece que num sistema de 32 bits memória é dividida em blocos de 32 bits ou 4 bytes, então a memória é alocada em múltiplos de 4 bytes.

Discordo!

typedef struct {
        char letra1;
        char letra2;
        char letra3;
} Dados;

Se testar para esse estrutura a resposta vai ser: 3 bytes, e não 4.

adicionado 2 minutos depois

O que implica a promoção é a presença de um tipo de 4 bytes.

adicionado 4 minutos depois

Não importa se ele está em cima, ou embaixo, ou no meio. Trata-se de uma otimização.

adicionado 6 minutos depois
13 minutos atrás, isrnick disse:

Isso também implica que a ordem dos itens na struct é importante, pois uma struct mal organizada pode aumentar muito o espaço ocupado pela struct.

Concordo!

  • Curtir 2
  • Obrigado 1
Postado

Ou mais precisamente na verdade tem isso:

+-------+-------+-------+-------+
|            numero1            |
+-------+-------+-------+-------+
|            numero2            |
+-------+-------+-------+-------+
| letra |           ?           |
+-------+-------+-------+-------+

 

  • Curtir 2
Postado

A parte que tem a interrogação, ainda sim é acessível (leitura e gravação).

#include <stdio.h>  /*  ~incluir: printf */
#include <limits.h>  /* ~incluir: INT_MAX */
#define str(val)  #val
struct sttnumero {
          char caractere;
          int inteiro;
};

/** funcao main ~ principal do programa  */
int main (void){
  struct sttnumero me = {0, INT_MAX};
    * (int *) & me.caractere = INT_MAX;
    printf ("SizeOf %s: %u\n", str (me), sizeof me);
    printf ("Inteiro %s: %d\n", str (me.caractere), * (int *) & me.caractere);
    printf ("Inteiro %s: %d\n\n", str (me.inteiro), me.inteiro);
    
    printf ("Point %s: %u\n", str (me), & me);
    printf ("Point %s: %u\n", str (me.caractere), & me.caractere);
    printf ("Point %s: %u\n", str (me.inteiro), & me.inteiro);
  return 0;
}

Ps.: Bem previsível! 

adicionado 8 minutos depois

Ou seja com conhecimento em ponteiro, e melhor declarar essa estrutura assim:

struct sttnumero {
          char caractere;
          char inteiro[sizeof (int)];
};

E não se perderá memória!

adicionado 16 minutos depois

Dúvidas, ou sugestões?

  • Curtir 2
Postado

Só adicionei no código do @AnsiC para imprimir cada byte separadamente em hexadecimal:

 

#include <stdio.h>  /*  ~incluir: printf */
#include <limits.h>  /* ~incluir: INT_MAX */
#define str(val)  #val
struct sttnumero {
          char caractere;
          int inteiro;
};

/** funcao main ~ principal do programa  */
int main (void){
  struct sttnumero me = {0, INT_MAX};
    * (int *) & me.caractere = 0x04030201;
    printf ("SizeOf %s: %u\n", str (me), sizeof me);
    printf ("Inteiro %s: %d\n", str (me.caractere), * (int *) & me.caractere);
    printf ("Inteiro %s: %d\n", str (me.inteiro), me.inteiro);
    for(int i = 0; i < 4; i++){
        printf ("Char %d: 0x%02hhx\n", i, *(&me.caractere + i) );
    }
    
    printf ("\nPoint %s: %u\n", str (me), &me);
    printf ("Point %s: %u\n", str (me.caractere), &me.caractere);
    printf ("Point %s: %u\n", str (me.inteiro), &me.inteiro);
  return 0;
}

 

  • Curtir 1
  • Obrigado 1

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...