Ir ao conteúdo
  • Cadastre-se

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


ruanzeferino

Posts recomendados

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
Link para o comentário
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);

 

  • Curtir 2
Link para o comentário
Compartilhar em outros sites

  • Membro VIP

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?

  • Obrigado 2
Link para o comentário
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.

  • Obrigado 2
Link para o comentário
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.

 

Link para o comentário
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
Link para o comentário
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.

  • Obrigado 1
Link para o comentário
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
Link para o comentário
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
Link para o comentário
Compartilhar em outros sites

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...