Ir para conteúdo
Fórum Script Brasil
  • 0

Aritmética de ponteiros com Dev C


AlexPocosC

Pergunta

Olá pessoal,

Sou novo aqui no fórum, então se estou cometendo alguma irregularidade, me notifiquem por favor. O meu problema é o seguinte: estou usando compilador Dev C++ versão 4.9.9.2 em Windows XP e o seguinte código não está fornecendo o resultado esperado:

#include <dos.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <time.h>

typedef unsigned char byte;

struct t_medicamento
    {
     char codigo[10];          
     int categoria;            
     char principioativo[50];
    };

    
    int main()
    {
   struct t_medicamento medicamento;
   void *ptrRegistro;
   byte *ptrByteRegistro;
   char *ptrCharRegistro;
   char strCampo1[30], strCampo2[30], strCampo3[30];
   

   strcpy(medicamento.codigo, "XYZ");
   medicamento.categoria = 5;
   strcpy(medicamento.principioativo, "ABCDEF");
   
   ptrByteRegistro = (byte*)(&medicamento);
   ptrRegistro = ptrByteRegistro;
   sprintf(strCampo1, "%s", (char*)(ptrRegistro));
   
   ptrRegistro = ptrByteRegistro + 10*sizeof(char);
   sprintf(strCampo2, "%d", *((int*)(ptrRegistro)));
   
   ptrRegistro = ptrByteRegistro + 10*sizeof(char) + sizeof(int);
   sprintf(strCampo3, "%s", (char*)ptrRegistro);
   
   printf("%s\n", strCampo1);
   printf("%s\n", strCampo2);
   printf("%s\n", strCampo3);
   getch();
   
   return 1;
 }

Ou seja, eu esperaria que no final fossem impressas as strings "XYZ", "5" e "ABCDEF", correto? No entanto, dependendo dos tamanhos dos campos de código e princípio ativo (que no código de exemplo estão com 10 e 50 bytes, respectivamente) às vezes aparece só "YZ" e "BCDEF", por exemplo. O que pode estar acontecendo? Muito obrigado.

Link para o comentário
Compartilhar em outros sites

7 respostass a esta questão

Posts Recomendados

  • 0

A organização da memória de uma struct não fica exatamente como você definiu, portanto não é válido confiar somente na declaração da struct para ler os dados diretamente.

Por exemplo, aqui no Visual Studio há um espaçamento de 2 bytes entre a variável codigo e a categoria (isto é, categoria começa 12 bytes depois de codigo).

O ideal é acessar os dados normalmente.

O seguinte código funcionou comigo:

#include <conio.h>
#include <stdio.h>
#include <string.h>

typedef char byte;

struct t_medicamento
{
    char codigo[10];
    int categoria;
    char principioativo[50];
};

    
int main(){
   struct t_medicamento medicamento;
   void *ptrRegistro;
   byte *ptrByteRegistro;
   char *ptrCharRegistro;
   char strCampo1[30], strCampo2[30], strCampo3[30];
  
   strcpy(medicamento.codigo, "XYZ");
   medicamento.categoria = 5;
   strcpy(medicamento.principioativo, "ABCDEF");


  
   ptrByteRegistro = (byte*)(&medicamento);
   ptrRegistro = ptrByteRegistro;
   sprintf(strCampo1, "%s", (char*)(ptrRegistro));
  
   ptrRegistro = ptrByteRegistro + 12*sizeof(char);
   printf("categoria: %d\n\n",medicamento.categoria);
   printf("valor: %d\n",*((int*)ptrRegistro));
   sprintf(strCampo2, "%d", *((int*)(ptrRegistro)));
  
   ptrRegistro = ptrByteRegistro + 12*sizeof(char) + sizeof(int);
   sprintf(strCampo3, "%s", (char*)ptrRegistro);
  
   printf("-%s-\n", strCampo1);
   printf("-%s-\n", strCampo2);
   printf("-%s-\n", strCampo3);
   getch();
  
   return 0;
}

No entanto, isso pode variar dependendo do compilador.

Obs.:

Removi algumas bibliotecas desnecessárias.

Link para o comentário
Compartilhar em outros sites

  • 0

Tente:

#pragma pack(push)
#pragma pack(1)

struct t_medicamento {
     char codigo[10];          
     int categoria;            
     char principioativo[50];
};

#pragma pack(pop)

Não tenho certeza se este funciona com o compilador MinGW ("Dev-C++").

Abraços.

Link para o comentário
Compartilhar em outros sites

  • 0

jonathan, durub, isso tem a ver com o alinhamento da palavra na memoria (foi mal, não sei qual o termo tecnico)??

aquele esquema de q, num processador de 32 bits ele so aloca uma variavel a cada 4 bytes (a não ser q ela seja menor do q isso e não va ficar dividida entre dois enderecos multiplos de 4).

e durub, esse codigo do pragma pack q você passou, serviria pra q esse alinhamento não seja seguido??

Link para o comentário
Compartilhar em outros sites

  • 0

Realmente, traduzindo pro português literalmente, seria "palavra", "palavra dupla", "palavra quadrática". (16 bits, 32 bits, 64 bits)

Pelo pouco que li, parece que o compilador alinha a struct com o maior tamanho de uma variavel possivel. Exemplo:

struct {
    char var;
    char var2;
}; /* alinhamento = 1 byte */

struct {
    char var;
    char var2;
    short var3;
} /* alinhamento = 2 bytes, mas nesse caso, não tem padding:
      | 1 byte - char
      | 1 byte - char
      2 bytes - short
      ------------------
      4 bytes (2 char + 1 short) */

struct {
      char var;
      short var3;
      char var2;
} /* alinhamento = 2 bytes e tem padding:
      2 bytes - char (1 de padding)
      2 bytes - short
      2 bytes - char (1 de padding)
          -----------------------------------
          6 bytes (2 char + 1 short + 2 char) */
Talvez não seja exatamente assim, mas é mais ou menos o básico. Não li muito nessa parte. Sobre o código, realmente não tenho certeza. Me lembro que é alguma coisa parecida, e acho que já vi o pragma pack por aí. (provavelmente é do VC++) Da documentação do GCC (6.37): packed The packed attribute specifies that a variable or structure field should have the smallest possible alignment—one byte for a variable, and one bit for a field, unless you specify a larger value with the aligned attribute. No GCC tem síntaxe diferente, o exemplo que ele dá é o seguinte:
/* Here is a structure in which the field x is packed, so that it immediately follows a:
              ou seja, não tem padding */
          struct foo
          {
            char a;
            int x[2] __attribute__ ((packed));
          };

Alguns programas fazem o padding manualmente, provavelmente para não dar problema. Já vi utilizarem isso no Blender.

Abraços.

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,3k
    • Posts
      652,4k
×
×
  • Criar Novo...