Ir ao conteúdo
  • Comunicados

    • Gabriel Torres

      Seja um moderador do Clube do Hardware!   12-02-2016

      Prezados membros do Clube do Hardware, Está aberto o processo de seleção de novos moderadores para diversos setores ou áreas do Clube do Hardware. Os requisitos são:   Pelo menos 500 posts e um ano de cadastro; Boa frequência de participação; Ser respeitoso, cordial e educado com os demais membros; Ter bom nível de português; Ter razoável conhecimento da área em que pretende atuar; Saber trabalhar em equipe (com os moderadores, coordenadores e administradores).   Os interessados deverão enviar uma mensagem privada para o usuário @Equipe Clube do Hardware com o título "Candidato a moderador". A mensagem deverá conter respostas às perguntas abaixo:   Qual o seu nome completo? Qual sua data de nascimento? Qual sua formação/profissão? Já atuou como moderador em algo outro fórum, se sim, qual? De forma sucinta, explique o porquê de querer ser moderador do fórum e conte-nos um pouco sobre você.   OBS: Não se trata de função remunerada. Todos que fazem parte do staff são voluntários.
    • DiF

      Poste seus códigos corretamente!   21-05-2016

      Prezados membros do Fórum do Clube do Hardware, O Fórum oferece um recurso chamado CODE, onde o ícone no painel do editor é  <>     O uso deste recurso é  imprescindível para uma melhor leitura, manter a organização, diferenciar de texto comum e principalmente evitar que os compiladores e IDEs acusem erro ao colar um código copiado daqui. Portanto convido-lhes para ler as instruções de como usar este recurso CODE neste tópico:  
ruanzeferino

C Como alocar dinâmicamente tipos diferentes em um vetor?

Recommended Posts

Pessoal, preciso fazer um projeto no qual eu devo alocar dinâmicamente struct, onde a
struct deve conter os seguintes campos:
 Código do medicamento;
 Preço de custo do medicamento (número real);
 Preço de venda do medicamento (número real);
 Tipo do produto (1-Uso livre; 2-Tarja vermelha; 3-Tarja preta);
 Quantidade disponível no estoque da farmácia
Eu queria saber se posso criar um ponteiro de ponteiros onde eu posso alocar dinâmicamente cada tipo da struct em uma posição desse vetor.
Eu pensei em criar um ponteiro de ponteiro void mas não sei como poderia por exemplo alocar uma linha desse tipo:
    aloc.precocust=(float*)malloc(n*sizeof(float));
Onde aloc seria tipo definido da struct.
É possível? Essa é a melhor forma? 
Sou iniciante

  • Obrigado 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não, você cria a struct:

//Declara a struct Medicamento
struct Medicamento {
    char codigo[16];
    double preco;
};

//Define o tipo Medicamento como sendo igual a struct Medicamento
typedef struct Medicamento Medicamento;

 

E depois usa malloc para criar um vetor que usa a struct como tipo...

//Ponteiro do tipo Medicamento aponta para a primeira posição
//da memória de 1000 posições com o tamanho da struct Medicamento
//cada, que foi alocada dinamicamente.
Medicamento *estoque = malloc(1000 * sizeof *estoque);

(Note que não se usa casting antes do malloc, isso é desnecessário e pode induzir ao erro.)

 

 

Aí basta acessar as posições alocadas incrementando sobre o ponteiro estoque para acessar cada struct alocada, e cada struct contém as variáveis definidas dentro na struct.

 

//Acessa o vetor de chars código da primeira struct
estoque[0].codigo;

//Acessa a variável double preco da centésima-primeira struct
estoque[100].preco;

 

E não pode esquecer de desalocar a memória que foi reservada dinamicamente:

free(estoque);

 

Editado por isrnick
Edit: centésima-primeira
  • Curtir 3

Compartilhar este post


Link para o post
Compartilhar em outros sites

Só um pequeno adendo:

12 horas atrás, isrnick disse:

//Acessa a variável double preco da centésima struct
estoque[100].preco;

 

Se 0 é a primeira, 100 seria  a centésima primeira (pois as posições do vetor irão de 0 a 999). Correto? :)

 

 

Sobre:

12 horas atrás, isrnick disse:

E não pode esquecer de desalocar a memória que foi reservada dinamicamente:


free(estoque);

 

Isso seria sempre antes de finalizar o programa? e se não der o free(), o espaço da memória fica "preso", por exemplo, até reiniciar o computador? caso sim, se rodar novamente esse programa ou outro, seria reutilizado a mesma região de memória ou a cada vez que rodar vai reservar outros espaços e vai chegar um ponto que vai estourar a memória?

  • Curtir 1
  • Obrigado 2

Compartilhar este post


Link para o post
Compartilhar em outros sites
3 horas atrás, Simon Viegas disse:

Se 0 é a primeira, 100 seria  a centésima primeira (pois as posições do vetor irão de 0 a 999). Correto? :)

Correto, eu corrigi isto. :thumbsup:

 

3 horas atrás, Simon Viegas disse:

Isso seria sempre antes de finalizar o programa? e se não der o free(), o espaço da memória fica "preso", por exemplo, até reiniciar o computador? caso sim, se rodar novamente esse programa ou outro, seria reutilizado a mesma região de memória ou a cada vez que rodar vai reservar outros espaços e vai chegar um ponto que vai estourar a memória?

Em sistema operacionais modernos quando o programa é finalizado a memória é liberada, e o espaço desalocado volta para o sistema operacional, então tecnicamente o free() não seria necessário se o programa é encerrado logo em seguida. Mas não usar o free() é um mau design mesmo nesse caso, pois ao alocar memória dinamicamente o programa é responsável pelo gerenciamento desta memória, logo deve ser responsável por libera-lá quando não necessita mais dela, então em C sempre deve-se usar free() para liberar memória alocada com malloc(), calloc() ou realloc().

 

Não liberar memória alocada dinamicamente vira um problema sério quando o código é parte de um programa maior, que pode ficar rodando por longos períodos no computador, e fazer muitas chamadas ao código que aloca memória sem nunca liberá-la, então é aí que você vê programas que ocupam mais e mais memória quanto mais tempo ficam abertos, ocupando recursos do computador desnecessariamente. Chamamos isso de memory leak (vazamento de memória), e pode ser bem complicado detectar onde o problema ocorre em programas com uma base de código grande.

 

Então minha recomendação é criar o hábito de imediatamente garantir que existe um free() correspondente para cada chamada a malloc(), toda vez que usar essa função no código, para evitar ter que ficar caçando agulha no palheiro no seu código no futuro.

  • Curtir 1
  • Obrigado 2

Compartilhar este post


Link para o post
Compartilhar em outros sites
22 horas atrás, ruanzeferino disse:

Eu queria saber se posso criar um ponteiro de ponteiros onde eu posso alocar dinâmicamente cada tipo da struct em uma posição desse vetor.

Não se pode declarar variáveis do tipo void, consequentemente, não também para array void; ainda assim essa regra não se aplica nos ponteiros void, ou sejo; eu acho que você pode sim que também são variáveis, mas essas são de uma outra classe categoria de variáveis.

 

Editado por AnsiC
melhorar a mensagem

Compartilhar este post


Link para o post
Compartilhar em outros sites
4 horas atrás, isrnick disse:

Em sistema operacionais modernos quando o programa é finalizado a memória é liberada, e o espaço desalocado volta para o sistema operacional, então tecnicamente o free() não seria necessário se o programa é encerrado logo em seguida.

Acredito que sempre deva ser liberada a memória com free se foi reservada dinamicamente no?

  • Obrigado 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
16 minutos atrás, vangodp disse:

Acredito que sempre deva ser liberada a memória com free se foi reservada dinamicamente no?

 

Sim, por segurança e consistência.

 

 

Na maioria dos sistemas operacionais (Windows, Linux, Unix, iOS, etc) após o programa ser encerrado o sistema operacional libera toda a memória associada ao programa, incluindo a memória alocada dinamicamente, isso é vantagem pois se o programa for interrompido no meio devido a um erro não deseja-se que a memória alocada dinamicamente fique "presa" por não ter sido liberada durante a execução do programa.

 

Entretanto em alguns sistemas não existe essa garantia de que a memória será liberada após o programa ser encerrado, por exemplo em sistemas embarcados onde pode não haver um SO que implementa esse recurso. Então, sempre usar free() seria uma garantia de sempre produzir código C que funciona corretamente em qualquer sistema.

 

 

Mas eu diria que sempre usar para ser consistente é uma razão ainda mais importante, pois aprender a sempre usar malloc() e free() juntos é algo simples que evita muitos problemas e dor de cabeça.

  • Curtir 1
  • Obrigado 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
1 hora atrás, isrnick disse:

incluindo a memória alocada dinamicamente,

Vei... sou um pouco incrédulo. Onde foi que você leu isso? Em todos os lugares que eu li sobre alocação dinâmica de memória nunca apareceu que a memória, do heap, fosse liberada automaticamente, somente tenho estou ciente que a pilha sim é liberada. Si perder o ponteiro que aponta para o heap, esse espaço fica perdido, assim que digamos que a regra de ouro é... "Reservou? Tem que liberar!". você tem algum articulo onde seja possível ler sobre o tema?

adicionado 2 minutos depois

Ja sabe como é internet... para nós que usamos esse recurso como única fonte de conhecimento as vezes podemos ler articulos desatualizados, por isso pergunto se conheces alguma fonte onde explique bem a coisa.

  • Obrigado 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

@vangodp Sim, buscando por "does heap get freed on program exit", "OS management of heap at application exit", "OS reclaim heap memory at application exit", várias respostas aparecem, logicamente existem diferenças em como a memória é gerenciada por cada sistema operacional, logo o modo como isso é feito varia, mas todos as informações basicamente afirmam a mesma coisa, o kernel que é responsável por gerenciar a memória do computador guarda a informação de que memória exatamente foi reservada para cada processo, e quando o processo é encerrado o kernel libera toda a memória no heap e demais locais alocados para aquele processo.

 

Seguem alguns:

https://unix.stackexchange.com/questions/275184/when-interrupting-a-process-does-a-memory-leak-occur

https://stackoverflow.com/questions/2213627/when-you-exit-a-c-application-is-the-malloc-ed-memory-automatically-freed

 

Mas é fácil testar isso, faça um simples programa que aloca uma grande quantidade de memória com malloc, mas não a libera com free, execute o programa e cheque a quantidade de memória usada durante a execução e após o programa ser finalizado. Ou execute o programa até o fim várias vezes em sequência, se a memória no heap não fosse liberada pelo kernel, eventualmente não haveria mais espaço disponível na memória, o que não é o caso.

  • Curtir 1
  • Obrigado 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

É bastante interessante o tema. Diria que fundamental saber, por isso pergunto, não fazia a menor ideia.

  • Curtir 2

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário






Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas publicações 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

×