This program is a double-linked list in C for my System's Software class.
Everything worked fine, until I coded the delete() and insert() functions.

The program compiles and executes on a window machine using Dev C++.
It also compiles without any errors or warnings on a linux machine using
gcc -g scan.c P3.c

However, when executing the a.out file, the program crashes with a segmentation fault.
My TA and I tried to find the bug for hours today, but to no avail. I would appreciate any help. Thanks.

Attachments
#include <stdio.h> #include <stdlib.h> #define XYZ 16 int main(int argc, char *argv[]) {
int i = 0, j = 0, 123.123 k = 0; int *array1, *array2; FILE *Input = fopen(argv[1], "rb"); FILE *Output = fopen(argv[2], "w");
int temp_Int = 0, count = 0; int temp_Array[MaxL]; char str[10]; if(Input != NULL){ while(!feof(Input))
{ fscanf(Input, "%d", &temp_Int); temp_Array[i] = temp_Int  ;
/* PROJECT 1 - Program 3   */
/* AUTHOR: Chris Goettel   */
/* DATE: 9/14/08            */
/* PURPOSE(paraphrased from Project 1 handout):    */
/*   The new features to the program are two functions, accessX() and accessV(), */
/*   that search a given linked list for either an index value or an actual value. */
/*   AccessX() takes three arguements (LL, i, head LL) and returns an integer.  */
/*   AccessV() takes three arguements (LL, V, head LL) and returns a Value. */
#include "scan.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* structure for location descriptor */
struct Value
{
   char Type;
   int Length;
   char Value[256];
};
/* structure for value descriptors */
struct Object
{
   char Status;
   struct Object *p_link;  // previous node
   struct Value *p_value;  // value
   struct Object *n_link;  // next node
};
/* head & tails for 4 lists */
struct Object *head_Ids, *tail_Ids;
struct Object *head_Numbers, *tail_Numbers;
struct Object *head_Seps, *tail_Seps;
struct Object *head_Unknown, *tail_Unknown;

/* list, append, and print fucntions for lists */
void list(struct Object *h, struct Object *t);
void append1(struct Object *node, struct Value val);
void append2(struct Object *node, struct Value val);
void append3(struct Object *node, struct Value val);
void append4(struct Object *node, struct Value val);
void print(struct Object *node, struct Object *head);

/* new search functions for Program 2 */
struct Value accessX(struct Object *node, int i, struct Object *head);
int accessV(struct Object *node, struct Value *val, struct Object *head);

/* new insert and delete functions for Program 3 */
struct Object *insert(struct Object *start, int num, struct Object *node);
struct Object *delete(struct Object *start, int num);
int length(struct Object *start);

int main(int argc, char *argv[])
{
   extern TKN get_token(FILE *);
   TKN Token;
   FILE *Input;
   /* 4 linked lists */
   struct Object *Ids, *Numbers, *Seps, *Unknown;
   int TokenNr = 1, LineNr = 1, Done = 0, num, num_half;
   /* the variables below are used to prove Program 2 specs */
   struct Value *Case1 = (struct Value *)malloc(sizeof(struct Value));
   struct Value *Case2 = (struct Value *)malloc(sizeof(struct Value));
   struct Value *Case3 = (struct Value *)malloc(sizeof(struct Value));
   struct Value *NullTest = (struct Value *)malloc(sizeof(struct Value));
   /* the variables below are used to prove Program 3 specs */
   struct Object *node4 = (struct Object *)malloc(sizeof(struct Object));
   struct Object *node5 = (struct Object *)malloc(sizeof(struct Object));
   struct Object *node6 = (struct Object *)malloc(sizeof(struct Object));

   strcpy(Case1->Value, "XYZ");
   strcpy(Case2->Value, "123.123");
   strcpy(Case3->Value, ";");
   strcpy(NullTest->Value, "COMPUTER");
   /* initialize lists */
   list(head_Ids, tail_Ids);
   list(head_Numbers, tail_Numbers);
   list(head_Seps, tail_Seps);
   list(head_Unknown, tail_Unknown);
   Input = fopen(argv[1], "r");
   while (!Done)
   {
      Token = get_token( Input );
      switch (Token.Code)
      {
         case 'I':
         {
           if(strlen(Token.String)<20)  /*less than 20 char? */
           {
             /* process identifier */
             struct Value *filler = (struct Value *)malloc(sizeof(struct Value));
             filler->Type = 'I';
             filler->Length = strlen(Token.String);
             strcpy(filler->Value, Token.String);
             Ids = (struct Object *)malloc(sizeof(struct Object));
             Ids->p_value = filler;
             append1(Ids, *filler);
             TokenNr = TokenNr+1;
           }
           break;
         }
         case 'N':
         {
           if(strlen(Token.String)<40)   /*less than 40 char? */
           {
           /* process integer number */
            struct Value *filler = (struct Value *)malloc(sizeof(struct Value));
            filler->Type = 'N';
            filler->Length = strlen(Token.String);
            strcpy(filler->Value, Token.String);
            Numbers = (struct Object *)malloc(sizeof(struct Object));
            Numbers->p_value = filler;
            append2(Numbers, *filler);
            TokenNr = TokenNr+1;
           }
           break;
         }
         case 'F':
         {
           if(strlen(Token.String)<40)  /*less than 40 char? */
           {
             /* process real number */
             struct Value *filler = (struct Value *)malloc(sizeof(struct Value));
             filler->Type = 'N';
             filler->Length = strlen(Token.String);
             strcpy(filler->Value, Token.String);
             Numbers = (struct Object *)malloc(sizeof(struct Object));
             Numbers->p_value = filler;
             append2(Numbers, *filler);
             TokenNr = TokenNr+1;
            }
           break;
         }
          case 'W':
         {
           /* process white space */
           struct Value *filler = (struct Value *)malloc(sizeof(struct Value));
           filler->Type = 'S';
           filler->Length = strlen(Token.String);
           strcpy(filler->Value, "white space");
           Seps = (struct Object *)malloc(sizeof(struct Object));
           Seps->p_value = filler;
           append3(Seps, *filler);
           break;
         }
         case 'L':
		 {
           /* process new line*/
           struct Value *filler = (struct Value *)malloc(sizeof(struct Value));
           filler->Type = 'T';
           filler->Length = strlen(Token.String);
           strcpy(filler->Value, "new line character");
           Seps = (struct Object *)malloc(sizeof(struct Object));
           Seps->p_value = filler;
           append3(Seps, *filler);
		   LineNr = LineNr+1;
	       TokenNr = 1;
         }
         case 'U':
         {
           if (Token.String[0] == 'Z')
           {
              Done = 1;
           }
           else
           {
              /* process unknown character*/
              struct Value *filler = (struct Value *)malloc(sizeof(struct Value));
              filler->Type = 'U';
              filler->Length = strlen(Token.String);
              strcpy(filler->Value, "unknown character");
              Unknown = (struct Object *)malloc(sizeof(struct Object));
              Unknown->p_value = filler;
              append4(Unknown, *filler);
           }
           break;
         }
         case 'O':
         {
           /* process operator*/
           struct Value *filler = (struct Value *)malloc(sizeof(struct Value));
           filler->Type = 'O';
           filler->Length = strlen(Token.String);
           strcpy(filler->Value, Token.String);
           Seps = (struct Object *)malloc(sizeof(struct Object));
           Seps->p_value = filler;
           append3(Seps, *filler);
           TokenNr = TokenNr+1;
           break;
         }
         case 'E':
         {
           struct Value *filler = (struct Value *)malloc(sizeof(struct Value));
           filler->Type = 'U';
           filler->Length = strlen(Token.String);
           strcpy(filler->Value, "unknown character");
           Unknown = (struct Object *)malloc(sizeof(struct Object));
           Unknown->p_value = filler;
           append4(Unknown, *filler);
           break;
         }
        }  /* end switch */
       } /* end while */

   /* printing Program 1 results */
   /* printf("IDS linked list: \n"); */
   /* print(Ids, head_Ids);   */
   /* printf("\nNUMBERS linked list:\n"); */
   /* print(Numbers, head_Numbers);  */
   /* printf("\nSEPS linked list: \n");  */
   /* print(Seps, head_Seps);      */
   /* printf("\nUNKNOWN linked list: \n"); */
   /* print(Unknown, head_Unknown); */
  /*  printf("\n");   */

   /* printing Program 3 results */
   /* Delete the 10-th identifier from list IDS and */
   /* replace with 7-th number from list NUMBERS */
   printf("The 7-th number in the list NUMBERS is ");
   *Case2 = accessX(Numbers, 7, head_Numbers);
   printf("'%s'. \n", Case2->Value);
   Case2->Type = 'N';
   Case2->Length = 1;
   node4->p_value = Case2;
   printf("Deleted 10th element in list IDS.\n");
   head_Ids = delete(head_Ids, 10);
   printf("Inserted 7-th element of NUMBERS into 10th index in list IDS.\n");
   head_Ids = insert(head_Ids, 10, node4);
   printf("\nIDS linked list: \n");
   print(Ids, head_Ids);
   printf("\n");
   /* Delete the 5-th number from list NUMBERS and */
   /* replace with 3-rd element from list SEPS */
   printf("The 3-rd separator in the list SEPS is ");
   *Case3 = accessX(Seps, 3, head_Seps);
   printf("'%s'. \n", Case3->Value);
   Case3->Type = 'S';
   Case3->Length = 1;
   node5->p_value = Case3;
   printf("Deleted 5th element in list NUMBERS.\n");
   head_Numbers = delete(head_Numbers, 5);
   printf("Inserted 3-rd element of SEPS into 5th index in list NUMBERS.\n");
   head_Numbers= insert(head_Numbers, 5, node5);
   printf("\nNUMBERS linked list:\n");
   print(Numbers, head_Numbers);
   printf("\n");
   /* Insert "&&" as 1-st element in list SEPS */
   strcpy(Case1->Value, "&&");
   Case1->Type = 'S';
   Case1->Length = 2;
   node6->p_value = Case1;
   printf("Inserted '&&' into 1st index in list SEPS.\n");
   head_Seps= insert(head_Seps, 1, node6);
   printf("\nSEPS linked list:\n");
   print(Seps, head_Seps);
   printf("\n");
   /* Print and then delete half of the objects in the list UNKNOWN */
   printf("\nUNKNOWN linked list: \n");
   print(Unknown, head_Unknown);
   num = length(head_Unknown);
   num_half = num / 2;
   printf("\nNow delete half the objects in list UNKNOWN \n");
   while(num > num_half)
   {
     printf("Deleted %d-th element in list UNKNOWN.\n", num);
     head_Unknown = delete(head_Unknown, num);
     num--;
   }
   /* Verify */
   printf("\nNew UNKNOWN linked list:\n");
   print(Unknown, head_Unknown);
   printf("\n");
   return 0;
}
/* initialize list to null */
void list(struct Object *h, struct Object *t)
{
    /* head & tail are null */
    h = NULL;
/* This scanner recognizes identifiers returning the token I */
/* integers returing the token N, reals returning the token F, */
/* white spaces (blancs and tabs mapped into just one white */
/* space) returning the token W, unprintable characters returning */
/* the token U, and other characters, returning the token O. */
/* In all casses the recognized lexeme is stored in the string */
/* variable Toke.String. */

#include "scan.h"

TKN  get_token (FILE *Input )
  {
   typedef struct  pt_entry
    {
     int    Action,
              Data;
    }  pt_node;

   static pt_node  PT[ 11 ][ 8 ] = {
    {{ 'S',  9  }, { 'S',  8  }, { 'S',  2  }, { 'S',  1  },
     { 'S',  1  }, { 'S',  8  }, { 'S',  8  }, { 'S', 10  }},
     
    {{ 'A', 'I' }, { 'A', 'I' }, { 'S',  1  }, { 'S',  1  },
     { 'S',  1  }, { 'A', 'I' }, { 'A', 'I' }, { 'A', 'I' }},
     
    {{ 'A', 'N' }, { 'A', 'N' }, { 'S',  2  }, { 'S',  5  },
     { 'A', 'N' }, { 'S',  3  }, { 'A', 'N' }, { 'A', 'N' }},
     
    {{ 'A', 'E' }, { 'A', 'E' }, { 'S',  4  }, { 'A', 'E' },
     { 'A', 'E' }, { 'A', 'E' }, { 'A', 'E' }, { 'A', 'E' }},
     
    {{ 'A', 'F' }, { 'A', 'F' }, { 'S',  4  }, { 'S',  5  },
     { 'A', 'F' }, { 'A', 'F' }, { 'A', 'F' }, { 'A', 'F' }},
     
    {{ 'A', 'E' }, { 'A', 'E' }, { 'S',  7  }, { 'A', 'E' },
     { 'A', 'E' }, { 'A', 'E' }, { 'S',  6  }, { 'A', 'E' }},
     
    {{ 'A', 'E' }, { 'A', 'E' }, { 'S',  7  }, { 'A', 'E' },
     { 'A', 'E' }, { 'A', 'E' }, { 'A', 'E' }, { 'A', 'E' }},
     
    {{ 'A', 'F' }, { 'A', 'F' }, { 'S',  7  }, { 'A', 'F' },
     { 'A', 'F' }, { 'A', 'F' }, { 'A', 'F' }, { 'A', 'F' }},
     
    {{ 'A', 'O' }, { 'A', 'O' }, { 'A', 'O' }, { 'A', 'O' },
     { 'A', 'O' }, { 'A', 'O' }, { 'A', 'O' }, { 'A', 'O' }},
     
    {{ 'A', 'U' }, { 'A', 'U' }, { 'A', 'U' }, { 'A', 'U' },
     { 'A', 'U' }, { 'A', 'U' }, { 'A', 'U' }, { 'A', 'U' }},
     
    {{ 'A', 'W' }, { 'A', 'W' }, { 'A', 'W' }, { 'A', 'W' },
     { 'A', 'W' }, { 'A', 'W' }, { 'A', 'W' }, { 'S', 10  }} };

   static int  TOKENS[ ] = {
      0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
      7, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 1, 6, 5, 1, 
      2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 
      1, 4, 4, 4, 4, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
      4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 
      1, 4, 4, 4, 4, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
      4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 1, 1, 0  };

    int  C, R = 0, S = 0, ch;
    TKN  Tkn;
    ch = getc(Input);
    if (( ch != EOF ) && (ch != '\n'))
      C = TOKENS[ ch ];
    else if (ch == EOF)
        {
         Tkn.Code = 'U';
         Tkn.String[ 0 ] = 'Z';
         Tkn.String[ 1 ] = '\0';
         return ( Tkn );
        }
     else
        {
         Tkn.Code = 'L';
	 Tkn.String[0] = '\n';
	 Tkn.String[1] = '\0';
         return (Tkn); 
        } 
     while (1) 
          if ( PT[ R ][ C ].Action == 'S' )
           {
            Tkn.String[ S++ ] = ch;
            ch = getc(Input);
	    if (ch == '\n') 
              {
               Tkn.String[ S ] = '\0';
               R = PT[ R ][ C ].Data;
               C = TOKENS[ ch ];
               Tkn.Code = PT[ R ][ C ].Data; 
               ungetc(ch, Input);
               return (Tkn);
	      } 
	    else
              {
               R = PT[ R ][ C ].Data;
               C = TOKENS[ ch ];
	      }
           }
         else
           {
            Tkn.String[ S ] = '\0';
            Tkn.Code = PT[ R ][ C ].Data; 
            ungetc(ch, Input);
            return (Tkn);
           }
  }
/* Note: this scanner assumes that the length of the longest string */
/* it recognizes is a constant MAX_STRING decleared in the application */
/* where it is  used */
#include <stdio.h>
#define  MAX_STRING    32
typedef struct t_node
 {
  char  Code;
  char  String[ MAX_STRING ];
 }  TKN,  *TKN_PTR;
struct Object *delete(struct Object *start, int num)
{
      int i = 1;

counting in C and C++ always starts with 0, not 1.

I didn't get seg fault

The 7-th number in the list NUMBERS is '2'.
Deleted 10th element in list IDS.
Inserted 7-th element of NUMBERS into 10th index in list IDS.

IDS linked list:
I, 7, include
I, 5, stdio
I, 1, h
I, 7, include
I, 6, stdlib
I, 1, h
I, 6, define
I, 3, XYZ
I, 3, int
N, 1, 2
I, 4, main
I, 4, argc
I, 4, char
I, 4, argv
I, 3, int
I, 1, i
I, 1, j
I, 1, k
I, 3, int
I, 6, array1
I, 6, array2
I, 4, FILE
I, 5, Input
I, 5, fopen
I, 4, argv
I, 2, rb
I, 4, FILE
I, 6, Output
I, 5, fopen
I, 4, argv
I, 1, w
I, 3, int
I, 4, temp
I, 3, Int
I, 5, count
I, 3, int
I, 4, temp
I, 5, Array
I, 4, MaxL
I, 4, char
I, 3, str
I, 2, if
I, 5, Input
I, 4, NULL
I, 5, while
I, 4, feof
I, 5, Input
I, 6, fscanf
I, 5, Input
I, 1, d
I, 4, temp
I, 3, Int
I, 4, temp
I, 5, Array
I, 1, i
I, 4, temp
I, 3, Int

The 3-rd separator in the list SEPS is '<'.
Deleted 5th element in list NUMBERS.
Inserted 3-rd element of SEPS into 5th index in list NUMBERS.

NUMBERS linked list:
N, 2, 16
N, 1, 0
N, 1, 0
N, 7, 123.123
S, 1, <
N, 1, 0
N, 1, 2
N, 1, 0
N, 1, 0
N, 2, 10

Inserted '&&' into 1st index in list SEPS.

SEPS linked list:
S, 2, &&
O, 1, #
S, 1, white space
O, 1, <
O, 1, .
O, 1, >
S, 1, white space
O, 1, #
S, 1, white space
O, 1, <
O, 1, .
O, 1, >
S, 1, white space
O, 1, #
S, 1, white space
S, 1, white space
S, 1, white space
S, 1, white space
O, 1, (
S, 1, white space
O, 1, ,
S, 1, white space
S, 1, white space
O, 1, *
O, 1, [
O, 1, ]
O, 1, )
S, 1, white space
O, 1, {
T, 1, new line character
S, 1, white space
S, 1, white space
O, 1, =
S, 1, white space
O, 1, ,
S, 1, white space
S, 1, white space
O, 1, =
S, 1, white space
O, 1, ,
S, 1, white space
S, 1, white space
S, 1, white space
O, 1, =
S, 1, white space
O, 1, ;
S, 1, white space
S, 1, white space
O, 1, *
O, 1, ,
S, 1, white space
O, 1, *
O, 1, ;
S, 1, white space
S, 1, white space
O, 1, *
S, 1, white space
O, 1, =
S, 1, white space
O, 1, (
O, 1, [
O, 1, ]
O, 1, ,
S, 1, white space
O, 1, "
O, 1, "
O, 1, )
O, 1, ;
S, 1, white space
S, 1, white space
O, 1, *
S, 1, white space
O, 1, =
S, 1, white space
O, 1, (
O, 1, [
O, 1, ]
O, 1, ,
S, 1, white space
O, 1, "
O, 1, "
O, 1, )
O, 1, ;
T, 1, new line character
S, 1, white space
O, 1, _
S, 1, white space
O, 1, =
S, 1, white space
O, 1, ,
S, 1, white space
S, 1, white space
O, 1, =
S, 1, white space
O, 1, ;
S, 1, white space
S, 1, white space
O, 1, _
O, 1, [
O, 1, ]
O, 1, ;
S, 1, white space
S, 1, white space
O, 1, [
O, 1, ]
O, 1, ;
S, 1, white space
O, 1, (
S, 1, white space
O, 1, !
O, 1, =
S, 1, white space
O, 1, )
O, 1, {
S, 1, white space
O, 1, (
O, 1, !
O, 1, (
O, 1, )
O, 1, )
T, 1, new line character
O, 1, {
S, 1, white space
O, 1, (
O, 1, ,
S, 1, white space
O, 1, "
O, 1, %
O, 1, "
O, 1, ,
S, 1, white space
O, 1, &
O, 1, _
O, 1, )
O, 1, ;
S, 1, white space
O, 1, _
O, 1, [
O, 1, ]
S, 1, white space
O, 1, =
S, 1, white space
O, 1, _
S, 1, white space
S, 1, white space
O, 1, ;
S, 1, white space
S, 1, white space
S, 1, white space
S, 1, white space


UNKNOWN linked list:
U, 1, unknown character
U, 1, unknown character
U, 1, unknown character
U, 1, unknown character
U, 1, unknown character
U, 1, unknown character
U, 1, unknown character
U, 1, unknown character

Now delete half the objects in list UNKNOWN
Deleted 8-th element in list UNKNOWN.
Deleted 7-th element in list UNKNOWN.
Deleted 6-th element in list UNKNOWN.
Deleted 5-th element in list UNKNOWN.

New UNKNOWN linked list:
U, 1, unknown character
U, 1, unknown character
U, 1, unknown character
U, 1, unknown character
U, 1, unknown character

Press any key to continue . . .

What did your core file tell you?

I don't have a linux machine to test it on and it is fine on my Sun, but it is probably a different architecture than you are using.

Generally Unix segmentation faults on a free are caused by over running a dynamic allocation. The failure will occur on a call to realfree. Once you find the allocation that is failing, you have to trace it back to the point where the array bounds were over written.

Try running Rational Purify on it if you can get a copy. It will show up as an array bounds write (ABW) problem.

Regrettably I have no time now to inspect your code more carefully but your list() initialization function is obviously wrong. It does initialize nothing because of it modifies by value copies of head/tail pointers only. It must have double indirection parameters to modify its arguments.

Hi,
I am not able to run the program in Windows using Eclipse, it give me error...
To get more info on core file, comile your sources with -g option like
cc P3.c -c -g P3.o
and then when the core is generated run the command
gdb a.out core
It will give you the details as in where the segmentation fault occured... You may want to use where command when in gdb mode...

Will analyse your code and let you know whats the issue...

This article has been dead for over six months. Start a new discussion instead.