3
Hello, I had asked a previous question about this problem, however I was able to solve but not learn about the problem itself so I tried to isolate it by creating a specific code for this problem and I would like someone to teach me what is happening and why it is wrong.
Follows the code:
#include <stdio.h>
#include <stdlib.h>
typedef struct Person
{
char name[256];
//char *name;
} person;
typedef struct Population
{
person p;
int num;
struct Population *next;
}people;
void insere_person(person *p){
printf("insira um nome: ");
scanf(" %s", p->name);
}
void insere_people(people *ps){
printf("insira um nome: ");
scanf(" %s", ps->p.name);
printf("insira um numero: ");
scanf(" %d", &ps->num);
}
void insere_person_to_people(person *p, people *ps){
insere_person(p);
printf("insira um numero: ");
scanf(" %d", &ps->num);
ps->p = *p;
}
short vazia(people *ps){
if(ps->next == NULL){ return 1; }
else{ return 0; }
}
void insere_teste(people *ps){
//char nome[256];
people *new_ps = (people *)malloc(sizeof(people));
printf("digite um nome:");
scanf(" %s", ps->p.name);
//scanf(" %s", nome);
new_ps->p = ps->p;
new_ps->next = NULL;
if(vazia(ps)){
ps->next = new_ps;
}
else{
people *tmp = ps->next;
while(tmp->next != NULL){
tmp = tmp->next;
}
tmp->next = new_ps;
}
}
void person_to_string(person *p){
printf("person{nome:%s}\n", p->name);
}
void people_to_string(people *ps){
printf("people{nome:%s, num:%d}\n", ps->p.name, ps->num);
}
void all_to_string(people *ps){
if(vazia(ps)){
printf("ninguem!\n");
return;
}
else{
people *tmp = ps->next;
while(tmp != NULL){
people_to_string(tmp);
tmp = tmp->next;
}
}
}
void menu(person *p, people *ps){
int op = -1;
while(op != 0){
printf("0 - sair\
\n1 - insere pessoa\
\n2 - insere populacao\
\n3 - mostra pessoa\
\n4 - mostra populacao\
\nopcao: ");
scanf(" %d", &op);
switch(op){
case 0:
break;
case 1:
insere_person(p);
break;
case 2:
//insere_people(ps); // funciona
//insere_person_to_people(p, ps); // funciona
insere_teste(ps); // não funciona
break;
case 3:
person_to_string(p);
break;
case 4:
//people_to_string(ps);
all_to_string(ps);
break;
default:
printf("Opcao invalida.\n");
break;
}
}
}
int main()
{
person p;
people ps;
menu(&p, &ps);
return 0;
}
Then after testing several ways to enter the data I realized that in the method "inse_test()" it error in the line:
scanf(" %s", ps->p.name);
I would like someone to explain me this mistake, because how to solve I already know, but it does not help me to know how to solve without understanding what happens.
Another point I would like to learn is why they are all being modified together, I know it is a pointer that is pointing to the same address, but I would like a more didactic explanation for this, because in practice I have already learned.
From now on, thank you very much.
Could you explain to me what a double pointer would be and what would be the difference between it and a normal pointer? Because this is a code isolated only from a problem I had and managed to solve, however solve without understanding it is no use, if you want I can post the original code here (I left it on github, then it has the previous versions).
– bruno101
@Bruno, I added an explanation about the double pointer, I hope I didn’t get too abstract.
– Brumazzi DB
Okay, correct me if I’m wrong, but from what I understand in case I do an assignment
**ptr_d = 7
it will change all the other values, right? So a double pointer is nothing more than a simple pointer extension, but when and why is it used?– bruno101
exactly the value is changed like this. The double pointer is usually using when one wants to change a pointer, as lists are usually done with a yes pointer (in most cases), it is using the double pointer to change them, as in the example on the link, where the pointer is started with
NULL
to set an end.– Brumazzi DB
Right, but now I got a little confused, I understood the HOW to use, but I didn’t understand the WHY to use, because I couldn’t use a simple pointer for this same example? What makes it more accurate, or necessary to create a pointer to this pointer?
– bruno101
@Bruno, The first reason is the semantics of the code, the second is the pointer be responsible for storing addresses, it is very likely that of memory error when trying to put an address in a variable that does not support it, because each type of variable needs to reserve an amount x memory, and pointers already have enough space for this, so we use dual pointers to store pointers.
– Brumazzi DB
I think I got it, but let’s see, the double pointer actually will allocate a new memory space to avoid conflicts or buffer bursts, that’s it?
– bruno101
Not conflicts, but buffers yes.
– Brumazzi DB
So I think now yes I understood, I will try to use in future projects, because then yes I can take the proof of this kkkk, thank you very much.
– bruno101