it may be a nooby question, but can you explain me why running this i get printed the last member of the list instead of the first? am i missing something?
struct nodo {
int info;
struct nodo *prec;
struct nodo *succ;
} ;
typedef struct nodo nodo;
nodo *leggi_lista(void);
int main (void) {
struct nodo *q;
q= NULL;
q=leggi_lista();
printf("%d\n\n", q->info); //should print first member of the list
return 0;
}
nodo *leggi_lista(void) { //creating list
nodo *p, *primo=NULL;
int i, n;
printf("Numero di elementi: ");
scanf("%d", &n);
printf("Inserisci %d numeri: ", n);
for (i=0; i<n; i++) {
p = malloc(sizeof(struct nodo));
scanf("%d", &p->info);
p->succ = primo;
primo = p;
}
return (primo) ;}
aaand i dunno what else i can add the post helper is bullying me :(
You are returning primo from the function which holds the value in p and this is got by the last malloc() and obviously you see the last value being printed out.
You need to fix your function to create the list. You need to keep your list's head intact and return the head from the function and print from head to end of list.
Related
Hi I'm trying to insert an element inside a list following a certain order(I have to add a equilateral triangle). When I try to use the code I can insert data(triangle measurements) but when I try to print list nothing appear :/.So I think that I wrote bad something in "inserisciPerPerimetro". Some word is written in italian and this is only a part of the code(two functions to add a triangle in my list),if u have to see also other parts let me know.
Thanks all!
This is my code:
typedef struct punto {
int x;
int y;
} PUNTO;
typedef struct triangolo {
PUNTO v;
int lato;
} TRIANGOLO;
typedef struct nodo {
TRIANGOLO t;
struct nodo *next;
} NODO;
int perimetro(TRIANGOLO t) {
return t.lato*3;
}
void stampaTriangolo(TRIANGOLO t) {
printf("Il triangolo ha il lato uguale a: %d con un perimetro pari a %d, il vertice in alto ha coordinate (%d,%d)\n",
t.lato, perimetro(t),t.v.x,t.v.y);
}
void stampaLista(NODO *head) {
if(head->next==NULL) {
printf("Lista vuota!\n");
} else {
while(head->next != NULL) {
head = head->next;
stampaTriangolo(head->t);
}
}
}
TRIANGOLO creaTriangolo() {
TRIANGOLO nuovo;
printf("Inserisci il lato del nuovo triangolo: ");
scanf("%d", &nuovo.lato);
printf("\n");
printf("Inserisci le coordinate del vertice con y maggiore:\n");
printf("x: ");
scanf("%d",&nuovo.v.x);
printf("\n");
printf("y: ");
scanf("%d",&nuovo.v.y);
printf("\n");
return nuovo;
}
void inserisciPerPerimetro(NODO *head) {
NODO* nuovoNodo;
nuovoNodo = malloc(sizeof(NODO));
nuovoNodo->t = creaTriangolo();
nuovoNodo->next = NULL;
if(head==NULL) {
head = nuovoNodo;
} else {
//Ordinamento per perimetro crescente
while(head->next != NULL)
if(perimetro(nuovoNodo->t) < perimetro(head->t)) {
nuovoNodo->next = head->next;
head->next = nuovoNodo;
} else {
head = head->next;
}
printf("Inserimento effettuato!\n");
}
}
int main() {
/* inizializza la lista */
NODO *head = malloc(sizeof(NODO));
head->next = NULL;
int risposta = -1; // per interazione con utente
while(risposta != 0) {
/* richiedi un'operazione all'utente */
printf("Che operazione vuoi svolgere?\n");
printf("1 -> Inserisci un triangolo nella lista ordinata secondo il perimetro crescente\n");
printf("2 -> Cancella il triangolo in testa alla lista\n");
printf("3 -> Visualizza la lista di triangoli\n");
printf("0 -> Termina il programma\n");
scanf("%d", &risposta);
/* gestisci le operazioni dell'utente */
if(risposta==1) {
inserisciPerPerimetro(head);
}
//else if(risposta==2)
//lista = cancellazione(lista);
else if(risposta==3) {
stampaLista(head);
}
else if(risposta==0) {
printf("Finito!\n\n");
}
else {
printf("Selezione non valida!\n\n");
}
}
}
I'm going to assume that you're holding a NODO* in some outer scope, and calling inserisciPerPerimetro on that pointer.
If you consider just the first time you do this (when the list is empty), your code will do head = nuovoNodo; so you will be putting the address of the newly allocated node into the pointer head. But this is a local copy of the parameter that you passed to the function, so the pointer in the outer scope will remain unchanged (and its value will be NULL). The next time you call the function, the list will still be empty.
One possible way to solve this is by passing a pointer to your head pointer to the function, so that the value of the pointer in the outer scope can be modified.
That is, the function should be defined like this:
void inserisciPerPerimetro(NODO **head)
Inside the function, modifications to head should be implemented as:
*head = nuovoNodo;
And in the outer scope you should have something like:
/*...*/
NODO* head = NULL;
inserisciPerPerimetro(&head);
/*...*/
EDIT:
Note that you are somewhat inconsistent with the node allocations: The head node is allocated in the outer scope (does it ever get its own triangle?), and all the others are allocated within the function. On the other hand, you check inside the function whether head is NULL - how can that happen if you allocate the list head in the outer scope?
Secondly, note that in the first call to inserisciPerPerimetro the while loop will be skipped because head->next is always NULL. This is because you don't handle the case where the new node needs to be inserted after the last node in the list.
The function should create a linked list of structs, I've seen in the debugger that it allocates the memory for the first element, but the program crashes during the allocation of memory for the second element.
struct Tipologia{
int mq;
int prezzo;
int n;
char descrizione[100];
};
struct Nodo{
struct Tipologia t;
struct Nodo *next;
};
typedef struct Nodo* NODO;
struct Tipologia creaTipologia(){
struct Tipologia t;
printf("MQ?\n");
scanf("%d", &(t.mq));
printf("PREZZO?\n");
scanf("%d", &(t.prezzo));
printf("DISPONIBILI?\n");
scanf("%d", &(t.n));
printf("DESCRIZIONE?\n");
int c;
while ( (c = getc(stdin)) != EOF && c != '\n');
fgets((t.descrizione), 100, stdin);
return t;
}
NODO costruisciPalazzo(){
int continua;
NODO h= NULL;
printf("VUOI COSTRUIRE UN APPARTAMENTO? 1 SI, 0 NO\n");
scanf("%d", &continua);
if(continua){
NODO n= malloc(sizeof(NODO));
h= n;
n->t= creaTipologia();
n->next= NULL;
printf("VUOI COSTRUIRE UN APPARTAMENTO? 1 SI, 0 NO\n");
scanf("%d", &continua);
while(continua){
NODO nodo= malloc(sizeof(NODO));
n->next= nodo;
n= nodo;
n->t= creaTipologia();
printf("VUOI COSTRUIRE UN APPARTAMENTO? 1 SI, 0 NO\n");
scanf("%d", &continua);
}
n->next= NULL;
}
return h;
}
I've been following the instructions of my professor but it keeps on crashing without giving any error to explain what actually happens. It seems to work for my classmates and we can't figure out what the problem is. Please help
The problem is that you are using a typedef that hides the fact that NODO is a pointer. This is bad, as it creates confusing situations where you are expecting a type to have a certain size and be used with a certain syntax, but in effect it's something entirely different.
For instance, you have to do this:
h= n;
n->t= creaTipologia();
n->next= NULL;
It's confusing that both h and n are not explicitly declared as pointers, but you have to use the arrow notation.
My suggestion is that you either remove completely the typedef and use struct nodo in your code, or at least remove the pointer from the typedef. Do the same with the other structure for consistency:
typedef struct {
int mq;
int prezzo;
int n;
char descrizione[100];
} TIPOLOGIA;
typedef struct Nodo {
TIPOLOGIA t;
struct Nodo *next;
} NODO;
You can also simplify your malloc using the object as a reference for its size. For instance:
NODO *h = malloc(sizeof *h);
This avoids the need of specifying the type of h when calling malloc. It's better for reuse too.
The problem was resolved simply by doing malloc(sizeof(struct Nodo)) instead of malloc(sizeof(NODO)), since with NODO it would allocate only the pointer, while with struct Nodo it allocates the whole element
Considering that i have two structs, where one point to other, how could i print a vallue from the second struct, caliing the first?
A brief explanation of the program bellow:
NODE, a struct that points to itselft to make a pile and to a generic pointer
ALUNO, the struct that the generic pointer in NODE will point to
createNode, function that allocates memory for the nodes
preencherNode, fills the pointer of node with the respective ALUNO
pushNode, creates a new node, pointing to the last created one, making a pile
criarAluno, allocates memory for ALUNO and fills it camps.
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int id;
float media;
} ALUNO;
typedef struct node
{
void *pointer;
struct node* link;
} NODE;
NODE* createNode(void)
{
NODE* topo;
topo=(NODE*)malloc(sizeof(NODE));
topo->pointer = NULL;
topo->link = NULL;
return(topo);
}
NODE* pushNode (NODE* topo)
{
NODE* novo;
novo=createNode();
novo->link=topo;
topo = novo;
return(topo);
}
NODE* preencherNode (NODE* topo, ALUNO* data)
{
topo->pointer=data;
return(topo);
}
ALUNO* criarAluno(FILE* v)
{
ALUNO* aln;
aln=(ALUNO*)malloc(sizeof(ALUNO));
int x;
float y1,y2;
fscanf (v, "%d %f %f",&x,&y1,&y2);
aln->id=x;
y1=(y1+y2)/2;
aln->media=y1;
return(aln);
}
void printData (NODE* topo)
{
NODE* aux;
aux=topo;
ALUNO* aln;
while(aux->link!=NULL)
{
aln=((ALUNO*)(aux->link));
printf("ID: %d \n",aln->id);
printf("Media: %f \n",aln->media);
printf("........................ \n");
aux=aux->link;
}
}
void main ()
{
FILE *doc;
doc = fopen("documento.txt","r");
if (doc==NULL){
printf("Nao ha como abrir o arquivo");
return(-1);
}
NODE *pilha;
pilha=createNode();
ALUNO* aluno;
int x;
for(x=0;x<11;x++)
{
aluno=criarAluno(doc);
pilha=preencherNode(pilha,aluno);
pilha=pushNode(pilha);
}
printData(pilha);
}
So now, the function printData, is printing the allocated space memory of the value i want, but not the value.
Given as stated in question that you have NODE *node....
ALUNO *aluno;
aluno = (ALUNO *)(node->pointer)
printf("%d", aluno->id)
I'm having troubles passing by working on a list with "int" keys to a "char *" keys.
the struct looks like :
struct nodo {
char *info;
struct nodo *prec;
struct nodo *succ;
};
typedef struct nodo nodo;
and I'm trying to use a function i used a lot to fill a struct with int or float fields (adapted obviously):
struct nodo *Crealista(void) {
struct nodo *p, *primo, *back;
int i, n;
p = NULL;
primo = NULL;
back = NULL;
printf("Numero di elementi: ");
scanf("%d", &n);
assert(n!=0);
printf("inserisci %d numeri interi positivi: ", n);
for (i=0; i<n; i++) {
p = malloc(sizeof(struct nodo));
scanf("%c" /* or maybe s? i need a string for each nodo... */, p->info);
// i feel this is the line that needs some more work
p->prec = back;
p->succ = NULL;
if (p->prec)
p->prec->succ = p;
back = p;
}
primo = p;
while (primo != NULL && primo->prec != NULL)
primo = primo->prec;
return primo;
}
Any suggestions?
Just add & in scanf in the line you mentioned,
scanf(" %c", &p->info);
and give a space before %c in format string to " %c" so that it display text in format you want.
Hello guys i got a problem while running this code:
trying to run the printf in the comment i got a segfault, also without that i dont see my listed printed ad the function Stampa should do.
Probably i am missing something with pointers
#include <stdio.h>
#include <stdlib.h>
struct nodo { // double linked list
int info;
struct nodo *prec;
struct nodo *succ;
};
typedef struct nodo nodo;
struct nodo *Crealista(void);
void Stampa (struct nodo *nodo);
int main(int argc, const char * argv[]) {
struct nodo *p;
p = Crealista();
// printf("%d",p->succ->info);
Stampa(p);
return 0;
}
// this funct should print the whole list
void Stampa (struct nodo *p) {
while (p->succ != NULL ) {
printf("Value : %d \n", p->info);
p = p->succ;
}
}
// this funct should create list with n members and return a pointer to the first element
struct nodo *Crealista(void) {
struct nodo *p, *primo, *back;
int i, n;
p = NULL;
primo = NULL;
back = NULL;
printf("Numero di elementi: ");
scanf("%d", &n);
printf("inserisci %d numeri interi positivi: ", n);
for (i=0; i<n; i++) {
p = malloc(sizeof(struct nodo));
scanf("%d", &p->info);
p->prec = back;
p->succ = NULL;
back = p;
}
primo = p;
while (primo->prec != NULL) { primo = primo->prec;}
return(primo);
}
Stampa()
Let's look at what we want to do when we print the entire list:
If the current element is valid, then we want to print it.
Then, we want to iterate to the next element, and continue this loop.
That's not what your code does. Your code looks to see if the current element has a successor, and if it does, we print the current element's value.
That function should actually be:
void Stampa (struct nodo *p) {
while (p != NULL ) {
printf("Value: %d\n", p->info);
p = p->succ;
}
}
Crealista()
If you tell Crealista() to create a list of 0 elements, your final while loop will exhibit undefined behavior.
If you tell Crealista() to create a list of less than 2 elements, your commented printf() in main() will cause undefined behavior (if it was uncommented).
Doubly Linked Lists
You never update the value of nodo->succ. You only update the value of nodo->prev. Here's one example of how to do that:
if (p->prec)
p->prec->succ = p;
Putting all of this together
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
struct nodo {
int info;
struct nodo *prec;
struct nodo *succ;
};
typedef struct nodo nodo;
struct nodo *Crealista(void);
void Stampa (struct nodo *nodo);
int main(int argc, const char * argv[]) {
struct nodo *p;
p = Crealista();
Stampa(p);
}
// Print the list
void Stampa (struct nodo *p) {
while (p != NULL ) {
printf("Value: %d \n", p->info);
p = p->succ;
}
}
// Create a list of n elements
struct nodo *Crealista(void) {
int i, n;
struct nodo *p = NULL;
struct nodo *primo = NULL;
struct nodo *back = NULL;
printf("Numero di elementi: ");
scanf("%d", &n);
assert(n != 0);
printf("inserisci %d numeri interi positivi: ", n);
for (i=0; i<n; i++) {
p = malloc(sizeof(struct nodo));
scanf("%d", &p->info);
p->prec = back;
p->succ = NULL;
if (p->prec)
p->prec->succ = p;
back = p;
}
primo = p;
while (primo != NULL && primo->prec != NULL)
primo = primo->prec;
return primo;
}
Which when run...
Numero di elementi: 5
inserisci 5 numeri interi positivi: 1 2 3 4 5
Value: 1
Value: 2
Value: 3
Value: 4
Value: 5
The printf() call you have commented out will always exhibit undefined behavior when p->succ is NULL, as it will be when p points to the last (or only) element of the list. In that case, although the behavior is formally "undefined", it is quite likely to manifest as a segmentation fault.
In stampa add check
while(p!=NULL)
{
printf("Value %d",p->info);
p=p->succ;
}
You are probably accessing it when it is not allocated. Check it this way there is no problem if it reaches a null value also. And initial null value will not cause problem also(if used).
I have modified your code
// this funct should create list with n members and return a pointer to the first element
struct nodo *Crealista(void) {
struct nodo *p, *primo, *back;
int i, n;
p = NULL;
primo = NULL;
back = NULL;
printf("Numero di elementi: ");
scanf("%d", &n);
printf("inserisci %d numeri interi positivi: ", n);
p = (struct nodo *)malloc(sizeof(struct nodo));
scanf("%d", &p->info);
p->prec = back;
p->succ = NULL;
back = p;
for (i=1; i<n; i++) {
p = (struct nodo *)malloc(sizeof(struct nodo));
scanf("%d", &p->info);
p->prec = back;
p->prec->succ=p;
p->succ = NULL;
back = p;
}
primo = p;
while (primo->prec != NULL) { primo = primo->prec;}
return(primo);
}
You are not setting the succ pointer of previous node correctly. That is what causing you the problem. Check now.