PDA

View Full Version : [C] Segmentation fault (core dumped)


Dhavamba
31-08-2012, 08:34
Salve ho un problema in questo codice, l'errore è:
Segmentation fault (core dumped)

Metto solo un pezzo del codice perchè l'errore l'ho individuato e si trova nella stringa:

scanf("\n%c",&item);

Però non capisco il motivo visto che il metodo richiede quei parametri, perchè l'esecuzione mi dà questo errore???




#include <stdio.h>
#include <stdlib.h>

struct listNode {
char data;
struct listNode *nextPtr;
};

typedef struct listNode ListNode;
typedef ListNode *ListNodePtr;

void insert (ListNodePtr*sPtr, char value);
char delete (ListNodePtr*sPtr, char value);
int isEmpty (ListNodePtr sPtr);
void printList(ListNodePtr currentPtr);
void instruction(void);

int main()
{
ListNodePtr startPtr = NULL;
int choice;
char item;


instruction();
printf("? ");
scanf("%d", &choice);

while(choice != 3) {
switch(choice)
{
case 1:
printf("Enter a character: ");
scanf("\n%c",&item);
insert(&startPtr, item);
printList(startPtr);
break;
......



comunque, non sò se può servire, ecco il sorgente completo




#include <stdio.h>
#include <stdlib.h>

struct listNode {
char data;
struct listNode *nextPtr;
};

typedef struct listNode ListNode;
typedef ListNode *ListNodePtr;

void insert (ListNodePtr*sPtr, char value);
char delete (ListNodePtr*sPtr, char value);
int isEmpty (ListNodePtr sPtr);
void printList(ListNodePtr currentPtr);
void instruction(void);

int main()
{
ListNodePtr startPtr = NULL;
int choice;
char item;


instruction();
printf("? ");
scanf("%d", &choice);

while(choice != 3) {
switch(choice)
{
case 1:
printf("Enter a character: ");
scanf("\n%c",&item);
insert(&startPtr, item);
printList(startPtr);
break;

case 2:
if ( !isEmpty( startPtr ) ) {
printf("Enter character to be deleted: ");
scanf("\n%c",&item);
if (delete(&startPtr, item)) {
printf("%c deleted.\n",item);
printList(startPtr); }
else {
printf("%c not found.\n\n", item); }
}
else printf("List is empty.\n\n");

break;

default:
printf("invalid choice.\n\n");
instruction();
break;
}
printf("?");
scanf("%d", &choice);
}

printf("End of Run.\n");
return 0;
}

void instruction(void)
{
printf("Enter your choice:\n"
"1 to insert an element into the list.\n"
"2 to delete an element from the list.\n"
"3 to end.\n");
}

void insert(ListNodePtr *sPtr, char value)
{
ListNodePtr newPtr;
ListNodePtr previousPtr;
ListNodePtr currentPtr;

newPtr = malloc(sizeof(ListNode));

if ( newPtr != NULL) {
newPtr->data = value;
newPtr->nextPtr = NULL;
currentPtr = *sPtr;

while (currentPtr != NULL && value > currentPtr->data) {
previousPtr = currentPtr;
currentPtr = currentPtr->nextPtr;
}
if ( previousPtr == NULL) {
newPtr->nextPtr = currentPtr; }
else {
previousPtr->nextPtr = currentPtr;
newPtr->nextPtr = currentPtr; }
}
else printf("%c not inserted.No memory available.\n",value);
}

char delete(ListNodePtr *sPtr, char value)
{
ListNodePtr tempPtr;
ListNodePtr previousPtr;
ListNodePtr currentPtr;

if(value == (*sPtr)->data) {
tempPtr = *sPtr;
*sPtr = (*sPtr)->nextPtr;
free(tempPtr);
return value; }
else {
previousPtr = *sPtr;
currentPtr = (*sPtr)->nextPtr;
while (currentPtr != NULL && currentPtr->data != value) {
previousPtr = currentPtr;
currentPtr = currentPtr->nextPtr; }
if (currentPtr != NULL) {
tempPtr = currentPtr;
previousPtr->nextPtr = currentPtr->nextPtr;
free(tempPtr);
return value; }
}
return '\0';
}

int isEmpty(ListNodePtr sPtr)
{
return sPtr == NULL;
}

void printList(ListNodePtr currentPtr)
{
if (currentPtr == NULL) printf("List is Empty.\n\n");
else {
printf("The list is:\n");
while(currentPtr != NULL) {
printf("%c --> ", currentPtr->data);
currentPtr = currentPtr->nextPtr; }
printf("NULL.\n\n");
}
}

__ZERO_UNO__
31-08-2012, 13:10
Ho provato a compilare con GCC e funziona (non proprio, l'inserimento non funziona correttamente). Comunque, ti consiglio di provare a mettere le parentesi per ogni case. Quindi


switch (...) {
case 1: {

}
case 2: {

}

...
}

sottovento
03-09-2012, 05:21
No, l'errore non e' li', ma nell'inserimento seguente: nella insert() cerchi di scandire la lista per cercare l'ultimo elemento ed appendere in coda.
Il ciclo while non verra' quindi mai eseguito; come risultato non assegni alcun valore alla variabile previousPtr, salvo poi utilizzarla. E questo fa arrabbiare il computer :D

Ovviamente la soluzione e' semplice, basta inizializzare previousPtr a NULL prima del ciclo


void insert(ListNodePtr *sPtr, char value)
{
ListNodePtr newPtr;
ListNodePtr previousPtr;
ListNodePtr currentPtr;

newPtr = (ListNodePtr)malloc(sizeof(ListNode)); // MEGI add cast

if ( newPtr != NULL) {
newPtr->data = value;
newPtr->nextPtr = NULL;
currentPtr = *sPtr;

/* A lista vuota non entri qui! */
while (currentPtr != NULL && value > currentPtr->data) {
previousPtr = currentPtr;
currentPtr = currentPtr->nextPtr;
}
/* quindi, qui previousPtr non ha alcun valore *.
if ( previousPtr == NULL) {
newPtr->nextPtr = currentPtr; }
else {
previousPtr->nextPtr = currentPtr;
newPtr->nextPtr = currentPtr; }
}
else printf("%c not inserted.No memory available.\n",value);
}