Well, the cause of the actual segmentation fault is simple to find.
Code:
(gdb) run
Starting program: ...
List (<ctrl-C> to quit):
1 - listClear()
2 - listHead()
3 - listTail()
4 - listPrev()
5 - listNext()
6 - listMoveToNth()
7 - listAddAfter()
8 - listAddBefore()
9 - listGetCurrent()
10 - listSetCurrent()
11 - listDelCurrent()
12 - listIsEmpty()
13 - listLength()
14 - listPosition()
CHOICE: 7
KEY(int) : 7
STRING(char *) : 7
============
NEW (CURRENT) STATE:
Program received signal SIGSEGV, Segmentation fault.
0x00000000004008ae in elementGetData (this=0x0) at Element.c:95
95 return(this->data);
(gdb) p *this
Cannot access memory at address 0x0
(gdb) l
90 * void
91 * ---------------------------------------------------------
92 */
93 void *elementGetData(Element *this)
94 {
95 return(this->data);
96
97 } /* elementGetData */
98
99
(gdb)
elementGetData() does not check for a NULL pointer.
But why is that point NULL in the first place? Well, that's going to be interesting . . .
I've annotated this a very little.
Code:
(gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: ...
List (<ctrl-C> to quit):
1 - listClear()
2 - listHead()
3 - listTail()
4 - listPrev()
5 - listNext()
6 - listMoveToNth()
7 - listAddAfter()
8 - listAddBefore()
9 - listGetCurrent()
10 - listSetCurrent()
11 - listDelCurrent()
12 - listIsEmpty()
13 - listLength()
14 - listPosition()
CHOICE: 7
KEY(int) : 7
STRING(char *) : 7
Breakpoint 1, listAddAfter (this=0x603010, data=0x604f60) at List.c:324
324 if (this->element_count >= MAX_SIZE) /*Array boundary check*/
(gdb) l
319 List *listAddAfter(List *this, void *data)
320 {
321 int i; /* loop index */
322 Element *new; /* new element */
323
324 if (this->element_count >= MAX_SIZE) /*Array boundary check*/
325 return (NULL);
326 if (!(new = elementCreate(data))) /*new element*/
327 return (NULL);
328
(gdb) n
326 if (!(new = elementCreate(data))) /*new element*/
(gdb)
329 if (this->element_count == 0)
(gdb) p *this
$2 = {element_count = 0, position = 0, elementArray = {
0x0 <repeats 999 times>}}
(gdb) n
331 this->elementArray[0] = new;
(gdb)
342 this->element_count++;
(gdb) p *this
$3 = {element_count = 0, position = 0, elementArray = {0x604f80,
0x0 <repeats 998 times>}}
(gdb) n
343 return(this);
(gdb)
345 } /* listAddAfter */
(gdb)
main () at ListMenu.c:153
153 printf("\n============\n\n");
(gdb)
============
154 printf("NEW (CURRENT) STATE:\n");
(gdb)
NEW (CURRENT) STATE:
156 savepos = listPosition(tst);
(gdb) p tst
$4 = (List *) 0x603010
(gdb) s
listPosition (this=0x603010) at List.c:578
578 return(this->position);
(gdb) p this
$5 = (List *) 0x603010
(gdb) p *this
$6 = {element_count = 1, position = 0, elementArray = {0x604f80,
0x0 <repeats 998 times>}}
(gdb) n
580 } /* listPosition */
(gdb)
main () at ListMenu.c:158
158 listHead(tst);
(gdb) p tst
$7 = (List *) 0x603010
(gdb) n
159 if (listIsEmpty(tst))
(gdb)
165 el = listGetCurrent(tst);
(gdb) p tst
$8 = (List *) 0x603010
(gdb) n
Program received signal SIGSEGV, Segmentation fault.
0x00000000004008ae in elementGetData (this=0x0) at Element.c:95
95 return(this->data);
Okay, so it's in the call to listGetCurrent that it segfaults. I add a breakpoint there.
Code:
(gdb) break listGetCurrent
Breakpoint 2 at 0x401379: file List.c, line 420.
(gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: ...
List (<ctrl-C> to quit):
1 - listClear()
2 - listHead()
3 - listTail()
4 - listPrev()
5 - listNext()
6 - listMoveToNth()
7 - listAddAfter()
8 - listAddBefore()
9 - listGetCurrent()
10 - listSetCurrent()
11 - listDelCurrent()
12 - listIsEmpty()
13 - listLength()
14 - listPosition()
CHOICE: 7
KEY(int) : 7
STRING(char *) : 7
Breakpoint 1, listAddAfter (this=0x603010, data=0x604f60) at List.c:324
324 if (this->element_count >= MAX_SIZE) /*Array boundary check*/
(gdb) c
Continuing.
============
NEW (CURRENT) STATE:
Breakpoint 2, listGetCurrent (this=0x603010) at List.c:420
420 if (this->element_count == 0)
(gdb) l
415 * NULL : list is empty
416 * ---------------------------------------------------------
417 */
418 void *listGetCurrent(List *this)
419 {
420 if (this->element_count == 0)
421 return(NULL);
422
423 return(elementGetData(this->elementArray[this->position]));
424
(gdb) s
423 return(elementGetData(this->elementArray[this->position]));
(gdb) s
elementGetData (this=0x0) at Element.c:95
95 return(this->data);
(gdb) p this
$9 = (Element *) 0x0
(gdb) p *this
$10 = {element_count = 1, position = 1, elementArray = {0x604f80,
0x0 <repeats 998 times>}}
(gdb)
In other words, you're trying to access elementArray[position], which is elementArray[1]; even though elementArray[0] is the only valid element.
So something is probably changing position where is shouldn't be.
Code:
$ grep -n position *.c
List.c:40: new->position = 0;
List.c:122: this->position = 0;
List.c:133: * - Adjust position to the beginning of provided list
List.c:141: * position references the first element in
List.c:152: this->position = 1;
List.c:165: * - Adjust position to the end of provided list
List.c:173: * position references the last element in
List.c:184: this->position = this->element_count;
List.c:200: * list is non-empty; list is not positioned at the
List.c:219: if ((this->position == 1) || (this->element_count < 2))
List.c:222: this->position--;
List.c:236: * list is non-empty; list is not positioned at the
List.c:240: * position now references the element
List.c:255: if ((this->position == this->element_count) || (this->element_count < 2))
List.c:258: this->position++;
List.c:275: * position now references the "Nth" element
List.c:291: this->position = n;
List.c:335: for (i = this->element_count ; i > this->position ; i--)
List.c:339: this->elementArray[this->position+1] = new;
List.c:386: for (i = this->element_count ; i > this->position-1 ; i--)
List.c:390: this->elementArray[this->position] = new;
List.c:391: this->position++;
List.c:423: return(elementGetData(this->elementArray[this->position]));
List.c:452: dval = elementGetData(this->elementArray[this->position]);
List.c:453: elementSetData(this->elementArray[this->position], data);
List.c:492: el = this->elementArray[this->position];
List.c:497: for (i = this->position ; i < this->element_count ; i++)
List.c:563: * - Obtain numeric value of current position in
List.c:570: * returns value of position
List.c:578: return(this->position);
$
I've highlighted the only code that could make the value of position 1. Lines 152, 258, 291, and 391.
Line 152 is here:
Code:
List *listHead(List *this)
{
if (this->element_count > 0)
{
this->position = 1;
return(this);
}
else
return(NULL);
} /* listHead */
I ran this through GDB:
Code:
(gdb) run
Starting program: ...
List (<ctrl-C> to quit):
1 - listClear()
2 - listHead()
3 - listTail()
4 - listPrev()
5 - listNext()
6 - listMoveToNth()
7 - listAddAfter()
8 - listAddBefore()
9 - listGetCurrent()
10 - listSetCurrent()
11 - listDelCurrent()
12 - listIsEmpty()
13 - listLength()
14 - listPosition()
CHOICE: 7
KEY(int) : 7
STRING(char *) : 7
============
NEW (CURRENT) STATE:
Breakpoint 1, listHead (this=0x603010) at List.c:150
150 if (this->element_count > 0)
(gdb) p *this
$1 = {element_count = 1, position = 0, elementArray = {0x604f80,
0x0 <repeats 998 times>}}
(gdb)
It seems that that is the problem. I'd change that line in listHead to this->position = 0; if I were you. When I do that, the "7-7-7" input works just fine.
So there you have it. An extended debugging session. Enjoy.