TransWikia.com

Devo alocar o membro da estrutura data também?

Stack Overflow em Português Asked by Jaime38130 on December 8, 2020

Assumindo a seguinte estrutura:

typedef struct lnode{
    struct lnode *next;
    void *data;
    int id;
}Lnode;

Digamos que quero guardar um Lnode no heap:

Lnode *exp = malloc(sizeof(*exp));

Devo agora também utilizar o malloc para o membro data?

exp->data = malloc(sizeof( void*)); ???

ou isto já acontece automaticamente quando aloco um Lnode?

3 Answers

Sim, deve. Cada objeto apontado por um ponteiro precisa estar alocado em algum lugar. Até pode ser alocado na stack, mas isto é raro e não funcionaria neste caso. Então todo objeto que será apontado por uma variável, mesmo que elas esteja dentro de uma estrutura, e será colocado no heap, deve ter a memória alocada com malloc() ou algum substituto dele.

Neste caso tanto next quanto data devem ter uma alocação antes.

Como eles são ponteiros estão apontando para onde? Como você pode obter um ponteiro? Existem duas formas básicas (tem outras, claro):

  • Uma é o uso do operador & que pega o endereço que alguma coisa. O mais comum é usar com coisas que estão na stack.
  • A outra é o uso de um alocador como o malloc() que retorna um endereço (um ponteiro.

Alocação automática em C só quando for stack, e só para o elemento na stack, obviamente não para possíveis apontamentos dentro dele.

exp->data = malloc(sizeof(void*));

Isto não funciona, ou pelo menos não faz o que você imagina. É uma flexibilidade ter o tipo void *, mas quando for alocar o espaço para objeto apontado por esse ponteiro, tem que saber o tamanho real deste objeto. Este caso está alocando espaço para um ponteiro, que provavelmente será 4 ou 8 bytes dependendo da arquitetura, só isto, não está alocando espaço para o dados que deveriam estar sendo armazenados.

Qual é o tamanho do objeto que vai em data? 50 bytes? Aloque 50 bytes. É o tamanho de 10 inteiros? aloque 10 * sizeof(int). E assim por diante.

Correct answer by Maniero on December 8, 2020

Quando alocas espaço para um objecto do tipo struct lnode estás a alocar espaço para todos os seus membros (dois ponteiros e um inteiro).

Cada um desses membros não está inicializado; ou seja, o valor de cada um dos membros não se pode usar. Mas podes atribuir um valor a cada membro.

struct lnode *exp = malloc(sizeof(*exp));
exp->next = NULL; /* OK */
exp->data = NULL; /* OK */
exp->id = 42;     /* OK */

Se quiseres que o membro data aponte para alguma coisa que já existe, podes lá meter esse endereço sem fazeres nova alocação.

double foobar = 3.14159;
exp->data = &foobar;

Se queres apontar para um objecto que ainda não existe, tens de alocar espaço para esse objecto e meter o endereço em data.

exp->data = malloc(sizeof (double));
if (!exp->data) { fprintf(stderr, "Sem memória.n"); exit(EXIT_FAILURE); }
*(double*)exp->data = 3.14159; // evita ponteiros para void!
// ...
free(exp->data);

Answered by pmg on December 8, 2020

Sim, como data é um ponteiro você deve alocar a memória para ele separadamente após ter alocado Lnode.

Quando você aloca a memória para Lnode será para a estrutura, ou seja, memória para o inteiro id e para dois ponteiros next e data, assim se você quiser armazenar algo nesses dois últimos terá que alocar memória para eles separadamente pois, repetindo, a alocação de Lnode aloca memória para seus ponteiros e não para o espaço que eles precisam para armazenar dados.

Answered by BrunoRB on December 8, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP