Newsgroup: it.comp.lang.c
Titolo: NULL POINTER

salve,
vi propongo questo dilemma...
che a me far diventare pazzo
perche' al termine del programma
da NULL POINTER ASSIGNEMET ??
quando tutti i puntatori sono correttamente assegnati
il programma crea una lista di 5 elementi
con inserimento in testa e in coda (senza ordinamento)
a voi ..miei     salvatori (spero !)
ciao daniele
#include <stdio.h>
#include <stdlib.h>
struct elemento{
 int valore;
 char carattere;
 struct elemento *succ;
 };
struct elemento *testa;
struct elemento *nuovo;
struct elemento *p;
int i,val,flag = 0;
void main()
{
 clrscr();
 randomize();
  printf("numeri generati\n");
  for(i = 0; i < 5; i++)
  {
 p = testa;
 val = random(10);
 printf("%d. ",val);
/* INSERISCE IN TESTA */
 if( testa == NULL && flag == 0)
 {
  testa -> valore = val;
  testa -> carattere = 65+i;
  flag = 1;
 }
 if(val <= testa->valore && flag == 1)
 {
    nuovo = (struct elemento *) malloc(sizeof(struct elemento));
    nuovo->valore = val;
    nuovo->carattere = 65+i;
    nuovo -> succ = testa;
    testa = nuovo;
 }
/* INSERISCE IN CODA ALLA LISTA */
 if(val > p->valore &&  flag == 1)
 {
    nuovo = (struct elemento *) malloc(sizeof(struct elemento));
    nuovo->valore = val;
    nuovo->carattere = 65+i;
  while(p->succ != NULL)
  {
    p = p->succ;
  }
  nuovo -> succ = NULL;
  p->succ = nuovo;
 }
  }
 p = testa;
 printf("\nnumeri nella lista\n");
 while(p != NULL)
 {
  printf("%d. ",p->valore);
  p = p->succ ;
 }
 printf("\n  pointer     Hex      Value     Hex->succ");
 printf("\n\n   (p)      %p :      %d          %p",p,*p,p->succ);
 printf("\n\n (nuovo)    %p :      %d
%p",nuovo,*nuovo,nuovo->succ);
 printf("\n\n (testa)    %p :      %d
%p",testa,*testa,testa->succ);
 p = testa;
 printf("\n\n   (p)      %p :      %d          %p",p,*p,p->succ);
 printf("\n\n\n");
}

Daniele Falloni (
uc...@tin.it
) wrote:
: salve,
: vi propongo questo dilemma...
: che a me far diventare pazzo
Esagerato...
: perche' al termine del programma
: da NULL POINTER ASSIGNEMET ??
: quando tutti i puntatori sono correttamente assegnati
Ma sei sicuro sicuro sicuro ?
[ snip ]
: /* INSERISCE IN TESTA */
[ snip ]
:  if( testa == NULL && flag == 0)
:  {
:   testa -> valore = val;
Cioe' fammi capire: se testa == NULL, allora tu assegni qualcosa a
testa->valore ?
[ snip ]
: /* INSERISCE IN CODA ALLA LISTA */
:  if(val > p->valore &&  flag == 1)
:  {
Alla prima iterazione p == NULL, giusto ? Pero' tu
lo dereferenzi lo stesso....
[ snip ]
:  printf("\n  pointer     Hex      Value     Hex->succ");
:  printf("\n\n   (p)      %p :      %d          %p",p,*p,p->succ);
Come mai stai tentando di visualizzare '*p' come un intero, dato che 
p e' definito come puntatore ad una struttura ?
Mi pare che questi bastino, per ora...;)
Ciao ciao,
Andrea
-- 
"...Unix, MS-DOS, and Windows NT (also known as the Good, the Bad, and 
 the Ugly)."
(by Matt Welsh)

 
if( testa == NULL && flag == 0)
{
// qui ci vuole una malloc (in C) o una new (in C++)
testa = (struct elemento *) malloc(sizeof(struct elemento));
// ora puoi dereferenziare il puntatore per l'assegnamento
testa -> valore = val;
La memoria deve sempre essere allocata e poi deallocata (con free
[delete in C++]).
Devi allocare tante strutture quati sono gli elementi della lista,
quindi la malloc deve essere utilizzata anche per creare gli elementi
successivi.
Per il resto giuste tutte le osservazioni di Andrea.
Ciao.
-- 
     (ZZZ)       Filippo Salotti, Bagni di Lucca, Lucca, Italy.
    //   \\  _                 E-mail : 
fil...@humnet.unipi.it
   /Y\    ZD<_o===============================================o
 .oZZZZZo.     | Studente Ingegneria Informatica Automatica  |
<OXXXXXXXO>    | Dip. Sistemi Elettrici Universita' di Pisa. |

Io assegno a testa il valore anche quando e' NULL
perche' significa che la lista e' Vuota !!  (giusto)
poi a seconda del valore che assume testa ...inserisco
in coda o in testa

  printf("\n\n   (p)      %p :      %d          %p",p,*p,p->succ);
Se vuoi visualizzare il valore memorizzato nella lista non devi scrivere
*p, *nuovo o *testa ma p -> valore, nuovo -> valore e testa -> valore.
Per il resto, compilato con il DJGPP sembra funzionare perfettamente.
EMG

...


 Per il resto, compilato con il DJGPP sembra funzionare perfettamente.
Ma non ti sembra che manchino un po' di malloc e di free?!


Io assegno a testa il valore anche quando e' NULL
E poi impazzisci quando il programma ti dice "NULL POINTER ASSIGNMENT" ?
NON PUOI ASSEGNARE ALCUN VALORE A TESTA FINQUANDO NON ALLOCHI MEMORIA PER
CONTENERLO !!!!!!!!
Andrea Laforgia
----
I guai ve li andate a cercare : 
quando Bill Gates annuncio' che avrebbe fatto scrivere 
Windows98 a Topo Gigio perche' non gli avete creduto ?

ok ?  (correggetemi se sbaglio)
La tua teoria e' assolutamente sbagliata !
"testa" e' un puntatore a una struttura non a un intero !
Cerchiamo di rispettare la semantica !
Ci perdi tanto a scrivere 
printf("%d", testa->valore) ???


Per il resto, compilato con il DJGPP sembra funzionare perfettamente.
Anche questo ?
 if( testa == NULL && flag == 0)
 {
  testa -> valore = val;
  testa -> carattere = 65+i;
  flag = 1;
 }


     else aggiunge_in_testa( (*p)->next, v ) ;
ERRATA CORRIGE : 
void aggiunge_in_testa ( struct elemento * * p , int v ) 
{
     if (*p == NULL)
     {
        if ( (*p = malloc( sizeof(struct elemento) ) ) != NULL )
        {
           (*p)->valore = v ;
           (*p)->next = NULL ;
        }
     }
     else aggiunge_in_testa( &(*p)->next, v ) ;


in coda o in testa
Sbagliato!
Se un pointer e' NULL a cio' a cui punta (cioe' nulla 'zero') non puoi
assegnare un bel niente. Semmai puoi cambiare il valore del pointer, ma non
e' quello che hai fatto nel tuo programma!
Se usi il BorlandC prova ad aggiungere questo Watch: "*(long*)0"
vedrai che dopo l'instruzione : testa->valore=val
cambiera' il suo valore da zero a val, cioe' hai scritto nella locazione
DS:0 per cui il programma terminando ti da il messaggio Null pointer
assignement
ciao
donCiccio

il puntatore della lista gia' punta al valore
Premetto che il tuo programma non l'ho provato.
L'istruzione *testa e' l'intera struttura puntata da testa, quindi ben 5
byte se compili MEDIUM o SMALL che vengono passati alla printf, tu vedi
correttamente il campo val, ma il pointer che viene stampato dopo non e'
giusto, perche' stai vedendo il resto della struttura e non l'ultimo
parametro 'p'.
ciao
donCiccio

 }
Se testa e' NULL come fai ad accedere agli elementi ???
Questo caso e' quello tipico dell'uso dei puntatori prima che essi vengano
inizializzati.
Dove per inizializzare non si intende assegnare il valore NULL ma un indirizzo
di memoria dove si e' sicuri che andando a scrivere non si provochi alcun danno.
Nel tuo caso tu scrivi nel contenuto puntato da testa ma non sai *dove* stai
mettendo quei dati e magari stai sovrascrivendo (o tentando di farlo) una parte
del s.o.
Nel caso lavori in modalita' reale ti si blocca il computer.
Nel caso lavori in modalita' protetta ottieni un errore di protezione.
Non e' una regola fissa, ma potrebbe capitare.
Se vuoi implementare una lista devi scrivere qualcosa del tipo :
void aggiunge_in_testa ( struct elemento * * p , int v ) ;
{
     if (*p == NULL)
     {
        if ( (*p = malloc( sizeof(struct elemento) ) ) != NULL )
        {
           (*p)->valore = v ;
           (*p)->next = NULL ;
        }
     }
     else aggiunge_in_testa( (*p)->next, v ) ;
}
Come vedi, le assegnazioni per il valore puntato da (*p) vengono effettuate solo
DOPO che e' stata allocata memoria sufficiente.
Inoltre volevo darti un consiglio : nel tuo codice delega parte del lavoro a
qualche funzione e ne avrai un vantaggio in termini di efficienza e
leggibilita'.


     else aggiunge_in_testa( (*p)->next, v ) ;
ERRATA CORRIGE : 
void aggiunge_in_testa ( struct elemento * * p , int v ) 
{
     if (*p == NULL)
     {
        if ( (*p = malloc( sizeof(struct elemento) ) ) != NULL )
        {
           (*p)->valore = v ;
           (*p)->next = NULL ;
        }
     }
     else aggiunge_in_testa( &(*p)->next, v ) ;


 ok ?  (correggetemi se sbaglio)
Secondo me è uno di quei comportamenti a rischio da evitare come la
peste.
EMG

Daniele Falloni (
uc...@tin.it
) wrote:
: Io assegno a testa il valore anche quando e' NULL
: perche' significa che la lista e' Vuota !!  (giusto)
Ti faccio notare che se testa vale NULL significa anche che 
il puntatore testa non punta a NULLA, in particolare /non/
punta ad un'area di memoria atta a memorizzare qualcosa.
: poi a seconda del valore che assume testa ...inserisco
: in coda o in testa
Bene, ti sarai reso conto di aver trovato almeno una delle
cause dell'errore che lamenti...


Daniele F (
uc...@tin.it
) wrote:
[ snip ]
: ok ?  (correggetemi se sbaglio)
Sbagli.


 Ma non ti sembra che manchino un po' di malloc e di free?!
Ehm, lo avevo guardato solo molto ma molto superficialmente. Questo
dimostra che non bisogna mai considerare corretto un programma solo
perché funziona...
EMG

  }
No, decisamente no...
EMG