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
?
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):
&
que pega o endereço que alguma coisa. O mais comum é usar com coisas que estão na stack.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
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP