fgets的链接列表程序分段错误?

时间:2012-11-08 15:37:35

标签: c linked-list segmentation-fault fgets

第一次工作正常。我可以添加一个项目,然后用显示功能显示。但是当我尝试添加第二个值时,只要我点击“a”就会出现一个段错误,就在fgets时。我在顶部评论过。

(除了Add,我还没有打扰过其他功能。)

#include    <stdio.h>
#include    <stdlib.h>
#include    <string.h>
#include    <ctype.h>
#include    "sortedll.h"

int     main(void)
{

int             intVal;
LNode           *headPtr = NULL;
char            buf[BUFLEN];
int             result;

do  {
    // ask the user what they want to do
    DisplayMenu();
    printf("Please enter a selection: ");
    fgets(buf, BUFLEN, stdin);
    *buf = toupper(*buf);
    switch (*buf)
        {
        case   'A':
            // prompt the user for a value; if we get one, add it to the
            // list
            printf("Please enter an integer value to add: ");
            fgets(buf, BUFLEN, stdin);

            //=======================================================================
            printf("check"); //doesn't print this second time around. seg fault at fgets?
            //=======================================================================

            if (1 != sscanf(buf, "%d", &intVal))
                {
                puts("Error reading the integer value...");
                }
            else
                {
                printf("1");
                headPtr = AddItem(headPtr, intVal);
                }
            break;

        case   'R':
            // if the list is empty display a message; else, get a value
            // from the user and attempt to remove it from the list
            if (NULL == headPtr)
                {
                puts("The list is currently empty...");
                }
            else
                {
                printf("Please enter an integer value to remove: ");
                fgets(buf, BUFLEN, stdin);
                if (1 != sscanf(buf, "%d", &intVal))
                    {
                    puts("Error reading the integer value...");
                    }
                else
                    {
                    headPtr = RemoveItem(headPtr, intVal);
                    }
                }
            break;

        case   'D':
            // display the current contents of the list
            result = DisplayList(headPtr);
            printf("Currently there %s %d node%s in the list.\n"
                                , (result != 1) ? "are" : "is"
                                , result
                                , (result != 1) ? "s" : "");
            break;

        case   'Q':
            // release all allocated memory and set the head pointer to
            // NULL to indicate that it is empty
            result = ReleaseMemory(headPtr);
            printf("There %s %d node%s released."
                                , (result != 1) ? "were" : "was"
                                , result
                                , (result != 1) ? "s" : "");
            headPtr = NULL;
            break;

        default:
            puts("Unrecognized option; please try again.");
            break;
        }
    puts(" ");

    } while ('Q' != *buf);

puts("Thanks for playing!  Bye!!\n");
return  0;

}  // end of "main"



// ==== AddItem ===============================================================


LNode*  AddItem(LNode  *headPtr, int  newItem)
{
    LNode *node = malloc(sizeof(*node));
    node->value = newItem;


    if(headPtr == NULL)
        {
        node->next = NULL;
        return node;
        }

    LNode *leadPtr = headPtr;
    LNode *trailPtr = headPtr;

    while(leadPtr->value != newItem)
        {
        leadPtr = leadPtr->next;
        trailPtr = leadPtr;
        }    

    leadPtr = leadPtr->next;
    free(trailPtr->next);    
    trailPtr->next = node;
    node->next = leadPtr;

    return headPtr;

}  // end of "AddItem"



// ==== DisplayList ===========================================================


int     DisplayList(LNode  *nodePtr)
{
    auto    int         counter = 0;

    // if the list is empty, indicate as such and return zero
    if (NULL == nodePtr)
        {
        puts("The list is currently empty...");
        return (0);
        }

    while (NULL != nodePtr)
        {
        printf("%d\n", nodePtr->value);
        nodePtr = nodePtr->next;
        counter++;
        }

    return (counter);

}  // end of "DisplayList"



// ==== DisplayMenu ===========================================================


void    DisplayMenu(void)
{
    puts("A)dd a value");
    puts("R)emove a value");
    puts("D)isplay the list");
    puts("Q)uit");

}  // end of "DisplayMenu"



// ==== ReleaseMemory =========================================================


int     ReleaseMemory(LNode  *headPtr)
{


}  // end of "ReleaseMemory"



// ==== RemoveItem ============================================================


LNode*  RemoveItem(LNode  *headPtr, int  targetItem)
{


}  // end of "RemoveItem"

2 个答案:

答案 0 :(得分:0)

当leadPtr可能为NULL时,您似乎试图访问leadPtr-&gt;值。

while(leadPtr->value != newItem)
    {
    leadPtr = leadPtr->next;
    trailPtr = leadPtr;
    }

在尝试访问其成员之前,您需要确保leadPtr!= NULL。

我建议您重构代码片段所属的功能,在内存访问方面看起来有点脆弱。

答案 1 :(得分:0)

你真的应该检查malloc调用的返回值:

LNode * node = malloc(sizeof(* node));

node-&gt; value = newItem;

如果你的堆空间不足会怎么样?