1) Sisi intendevo quello, non è la prima volta che utilizzo questa definizione di stringa e non ho mai avuto problemi con l'allocazione, mi fa tutto in automatico..
2) Sisi infatti non riuscivo a capire come creare il dizionario, cioè mi sembrava inutile un solo elemento.. ma in questo modo in pratica ho un doppio puntatore a un elemento dato.. giusto?
4) sisi lo so, ma avevo altri problemi piu gravi ahahahahha
3/5) Si io accedo sempre dal primo elemento inserito, ma in teoria quando cancello un elemento (se non è il primo non ho problemi) se è il primo o l'unico dovrei aggiornare il puntatore dal quale accedo (il famoso "list" che adesso è sparito ed è diventato *p) ... quindi se nella funzione cancella io aggiorno il puntatore dal quale accedo dovrebbe risolversi il problema... ma qui si ripone il problema dell'usare direttamente l'argomento che passo alla funzione e non un altro puntatore!)
Sto entrando in un tunnel di confusione dal quale prevedo non usciro facilmente... :S 

Comunque ti allego il codice rivisto grazie alle tue correzioni.. (ho lasciato invariata la definizione di stringa.. volevo vedere se dava problemi ma come puoi vedere va bene lo stesso)
codice:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef char * STRINGA;
typedef struct dato {
struct dato* prec;
int elemento;
STRINGA chiave;
struct dato* succ;
} DATO;
typedef DATO * DIZIONARIO;
void creadiz(DIZIONARIO *diz)
{
*diz = NULL;
}
void inserisci(DIZIONARIO *d, int el, STRINGA ch)
{
DATO *p;
p = malloc(sizeof(DATO));
p->elemento = el;
p->chiave = ch;
if ( (*d) == NULL) {
p->prec = p;
p->succ = p;
(*d) = p;
} else {
p->succ = (*d)->succ;
(*d)->succ->prec = p;
p->prec = (*d);
(*d)->succ = p;
}
}
int cancella(DIZIONARIO *d, STRINGA ch)
{
DATO *p = *d;
if (p == NULL) {
return -1;
} else {
do {
if( strcmp(p->chiave, ch) == 0 ) {
p->prec->succ = p->succ;
p->succ->prec = p->prec;
free(p);
return -10;
} else {
p = p->succ;
}
} while ( p != (*d) );
}
return -1;
}
int cerca(DIZIONARIO *d, STRINGA ch)
{
DATO *p = *d;
if (p == NULL) {
return -1;
} else {
do {
if( strcmp(p->chiave, ch) == 0 ) {
return p->elemento;
} else {
p = p->succ;
}
} while ( p != (*d) );
}
return -1;
}
e del main tanto per XD
codice:
int main(){
DIZIONARIO d;
creadiz(&d);
printf("Ciao, come stai?\n");
inserisci(&d, 1, "Ciao");
inserisci(&d, 2, "come");
inserisci(&d, 3, "stai");
printf("La parola \"Ciao\" si trova nella posizione: %d\n", cerca(&d, "Ciao"));
printf("La parola \"come\" si trova nella posizione: %d\n", cerca(&d, "come"));
printf("La parola \"stai\" si trova nella posizione: %d\n", cerca(&d, "stai"));
printf("La parola \"tutto\" si trova nella posizione: %d\n", cerca(&d, "tutto"));
printf("La parola \"bene\" si trova nella posizione: %d\n", cerca(&d, "bene"));
printf("La parola \"grazie\" si trova nella posizione: %d\n", cerca(&d, "grazie"));
printf("Ciao, tutto bene grazie.\n");
cancella(&d, "come");
inserisci(&d, 4, "tutto");
cancella(&d, "stai");
inserisci(&d, 5, "bene");
inserisci(&d, 6, "grazie");
printf("La parola \"Ciao\" si trova nella posizione: %d\n", cerca(&d, "Ciao"));
printf("La parola \"come\" si trova nella posizione: %d\n", cerca(&d, "come"));
printf("La parola \"stai\" si trova nella posizione: %d\n", cerca(&d, "stai"));
printf("La parola \"tutto\" si trova nella posizione: %d\n", cerca(&d, "tutto"));
printf("La parola \"bene\" si trova nella posizione: %d\n", cerca(&d, "bene"));
printf("La parola \"grazie\" si trova nella posizione: %d\n", cerca(&d, "grazie"));
system("pause");
return 0;
}