Visualizzazione dei risultati da 1 a 10 su 10
  1. #1

    [C] aggingere in coda ricorsivamente

    questa funzione mi dà un segmentation
    xchè nn riesce a aggingere il coda ricorsivamente?

    codice:
    /* Crea elementi successivi */
    hello *aggiungi(hello *p, int ins)
    {
    	hello *paus;
    	paus = malloc(sizeof(hello));
    	paus->n = ins;
    	paus->next = NULL;
    	if (p == NULL) {
    		p->next = paus;
    	}
    	else {
    		aggiungi(p->next, ins);
    	}
    	return p;
    }
    live free or die

  2. #2
    Invece che allocare un nuovo elemento e poi associarlo a quello che vuoi realmente allocare, prova ad allocare il diretto interessato, così:
    codice:
    /* Crea elementi successivi */
    hello *aggiungi(hello *p, int ins)
    {
    	if (p == NULL) {
    		p = malloc(sizeof(hello));
    		p->n = ins;
    		p->next = NULL;
    	}
    	else {
    		aggiungi(p->next, ins);
    	}
    	return p;
    }

    PS: Non so se questo risolverà l'errore, ma dovrebbe fargli risparmiare dei cicli di cpu inutili nel caso che passi alla funzione un puntatore già allocato, e dovrebbe migliorare il codice...

    PS2: Scusa... Ma se gli passi un'oggetto di tipo hello già allocato questa funzione ti restituisce lo stesso oggetto, e non quello che allochi... L'errore potrebbe dipendere proprio da questo se richiami la funzione ogni volta con un puntatore all'oggetto invece che con un puntatore al membro next dell'oggetto...
    Se vuoi evitare ciò devi mettere un:
    codice:
    p = aggiungi(p->next, ins);
    nell'else


  3. #3
    e *paus nn lo uso +?

    nn ho capito molto bene...
    live free or die

  4. #4
    Originariamente inviato da Kandalf
    e *paus nn lo uso +?

    nn ho capito molto bene...
    Mi so spiegare molto male :adhone:

    *paus lo usi soltanto come variabile temporanea: la allochi e poi la associ a p->... Se invece allochi direttamente p fai molto prima


    Nella funzione aggiungi() esegui un controllo per vedere se p è NULL oppure no...
    Se p è NULL devi allocarlo in memoria con la funzione malloc e inizializzargli le variabili...
    Se p invece non è NULL (quindi esiste già) devi richiamare la stessa funzione passandogli p->next, e questo avviene finchè non trovi l'ultimo valore di p, quello la cui variabile next non è stata ancora allocata... Quando viene trovata, la nuova variabile viene allocata e le funzioni vengono richiamate all'opposto (questo per la ricorsione)...
    Se te ogni volta allochi *paus, lo fai molte volte non necessarie... altrimenti lo faresti solo una volta...

    Ho scorto un altro piccolo erroretto...
    la funzione malloc restituisce un puntatore a void... Devi eseguire il cast perchè restituisca un valore del tipo voluto: p->next = (hello *) malloc (sizeof(hello));

    Prova a sostituire la tua funzione aggiungi con questa:

    codice:
    /* Crea elementi successivi */
    hello *aggiungi(hello *p, int ins)
    {
    	if (p == NULL) {
    		p = (hello *) malloc(sizeof(hello));
    		p->n = ins;
    		p->next = NULL;
    	}
    	else {
    		p = aggiungi(p->next, ins);
    	}
    	return p;
    }
    Se hai altre domande non esitare a porle


  5. #5
    Utente di HTML.it L'avatar di anx721
    Registrato dal
    Apr 2003
    Messaggi
    2,352
    Dunque, l'errore di segmentation fault è dovuto all'istruzione:
    Codice PHP:
    if (== NULL) {
            
    p->next paus;
        } 
    se p è NULL non puoi accedere al campo next!


    La versione che ti ha dato GNAWS non è corretta, se passi ad una funzione un puntatore p che è NULL, e all'interno della funzione inizializzi p con la malloc, all'uscita della funzione p è sempre NULL perchè in C gli argomenti sono passati per VALORE. Per fare quello che vuoi devi fermarti nelle chiamate ricorsive prima di arrivare all'elemento NULL. Quindi devi considerare 3 casi:

    1 - p == NULL: avviene all'inizio quando la lista e vuota: crei un nuovo oggetto hello con la malloc e lo ritorni;

    2 - p -> next == NULL: crei un nuovo oggetto hello con la malloc inizializzando p -> next con tale elemento;

    p -> next != NULL: richimi ricorsivamente la funzione. Un modo di scrivere la funzionè è allora:

    Codice PHP:
    hello *aggiungi(hello *pint ins)
    {
        if (
    == NULL) {
            
    = (hello *) malloc(sizeof(hello));
            
    -> ins;
            
    -> next NULL;
        }
        else if(
    -> next == NULL){
            
    -> next = (hello *) malloc(sizeof(hello));
            
    -> next -> ins;
            
    -> next -> next NULL;
            
    -> next;
        }
        else{
            
    aggiungi(-> nextins);
        }

        return 
    p;

    la funzione ritorna sempre l'ulitmo elemento inserito nella lista. Se lista è la variabile puntatore a hello che mantiene la lista, allora dovra essere inizilizzata col valore di ritorno della prima chiamata a aggiungi:

    hello *lista = NULL;
    lista = aggiungi(lista, 5);

    mentre le volte successive non devi asssegnare a lista il risultato di aggiungi se no lista non punterà piu alla testa della lista.


  6. #6
    ho provato con entrambi ma nn funziona...
    live free or die

  7. #7
    Utente di HTML.it L'avatar di anx721
    Registrato dal
    Apr 2003
    Messaggi
    2,352
    Originariamente inviato da Kandalf
    ho provato con entrambi ma nn funziona...
    Che cosa non ti funziona, spiega meglio il risultato che ottieni e come ti accorgi che non ti funziona, a me pare funzioni


  8. #8
    ho usato parte della tua funzione, dato che la mia lista nn puo' mai essere NULL, cmq ora mi interessa solo capire

    questo è il codice - spero di nn averlo modificato

    codice:
    #include <stdio.h>
    #include <stdlib.h>
    
    struct hello {
    	int n;
    	struct hello *next;
    };
    
    typedef struct hello hello;
    
    
    /* Funzione che crea il primo elemento */
    hello *crea(hello *p, int ins)
    {
    	p = malloc(sizeof(hello));
    	p->n = ins;
    	p->next = NULL;
    	return p;
    }
    
    /* Crea elementi successivi */
    hello *aggiungi(hello *p, int ins)
    {
    	hello *paus;
    	if (p->next == NULL) {
    		paus = malloc(sizeof(paus));
    		paus->n = ins;
    		paus->next = p;
    	} else {
    		p = aggiungi(p->next, ins);
    	}
    }
    
    /* Funzione ricorsiva che stampa la lista */
    void stampa(hello *p)
    {
    	if (p == NULL)
    		printf("NULL\n");
    	else {
    		printf("%d -> ", p->n);
    		stampa(p->next);
    	}
    }
    
    
    main()
    {
    	hello *puntLista;
    	int ins;
    	printf("Inserisci il primo elemnto - 0 per finire\n");
    	scanf("%d", &ins);
    	puntLista = crea(puntLista, ins);
    	while (ins != 0) {
    		printf("Inserisci elemento successivo\n");
    		scanf("%d", &ins);
    		puntLista = aggiungi(puntLista, ins);
    	}
    	stampa(puntLista);
    }
    questo è l'output
    codice:
    bash-2.05b$ gcc ll.c -o ll
    bash-2.05b$ ./ll
    Inserisci il primo elemnto - 0 per finire
    1
    Inserisci elemento successivo
    2
    Inserisci elemento successivo
    3
    Inserisci elemento successivo
    0
    1 -> NULL
    live free or die

  9. #9
    in modo iterativo mi funziona...se qualcuno è capace a farlo ricorsivo

    codice:
    #include <stdio.h>
    #include <stdlib.h>
    
    struct hello {
    	int n;
    	struct hello *next;
    };
    
    typedef struct hello hello;
    
    
    /* Funzione che crea il primo elemento */
    hello *crea(hello *p, int ins)
    {
    	p = malloc(sizeof(hello));
    	p->n = ins;
    	p->next = NULL;
    	return p;
    }
    
    /* Crea elementi successivi */
    hello *aggiungi(hello *p, int ins)
    {
    	hello *paus, *prev, *curr;
    	paus = malloc(sizeof(paus));
    	paus->n = ins;
    	paus->next = NULL;
    	
    	prev = NULL;
    	curr = p;
    	
    	while(curr != NULL) {
    		prev = curr;
    		curr = curr->next;
    	}
    		prev->next = paus;
    		paus->next = curr;
    	return p;
    	
    }
    
    /* Funzione ricorsiva che stampa la lista */
    void stampa(hello *p)
    {
    	if (p == NULL)
    		printf("NULL\n");
    	else {
    		printf("%d -> ", p->n);
    		stampa(p->next);
    	}
    }
    
    
    main()
    {
    	hello *puntLista;
    	int ins;
    	printf("Inserisci il primo elemnto - 0 per finire\n");
    	scanf("%d", &ins);
    	puntLista = crea(puntLista, ins);
    	while (ins != 0) {
    		printf("Inserisci elemento successivo\n");
    		scanf("%d", &ins);
    		puntLista = aggiungi(puntLista, ins);
    	}
    	stampa(puntLista);
    }
    live free or die

  10. #10
    Utente di HTML.it L'avatar di anx721
    Registrato dal
    Apr 2003
    Messaggi
    2,352
    Codice PHP:
    /* Crea elementi successivi */
    hello *aggiungi(hello *pint ins)
    {
        
    hello *paus;
        if (
    p->next == NULL) {
            
    paus malloc(sizeof(hello));
            
    paus->ins;
            
    paus->next NULL;
            
    p->next paus;
        } else {
            
    aggiungi(p->nextins);
        }
        return 
    paus;

    Non l'ho provata, ma dovrebbe essere giusta,


Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.