无法确定细分原因

时间:2017-04-24 18:46:28

标签: c struct segmentation-fault

我的程序的一部分是错误的并导致分段错误。因此,我想出一个程序,该程序可以读取大量有关学生记录的数据,例如ID,以及相应的成绩和学分。该数据存储在文本文件中。然后,在读入数据时,我的程序会创建一个学生记录的链接列表,按唯一ID排序。由于学生的ID可能会在文本文件中再次重复,因此我创建了一个搜索重复项的函数,这个函数在某处不正确,导致分段错误。这是功能:

struct SR *findDuplicate ( struct SR *head, int ID )
    {
        struct SR *temp = NULL;
        temp = malloc ( sizeof ( head ) );
        temp = head;
        while ( temp->ID != ID )
        {
            if ( temp->next != NULL )
            {
                temp = temp->next;
            }
            else 
            return NULL;
        }
        return temp;
    }

因此,当我运行调试器时,它会返回以下错误消息:

Program received signal SIGSEGV, Segmentation fault.
0x0000000000400deb in findDuplicate (head=0x7fffffffe540, ID=5304) at HW7.c:101
101                     while ( temp->ID != ID )

我无法弄清楚while循环有什么问题。在程序的某个地方,我已经将head.ID初始化为-1(因为文本文件中学生的ID永远不会为负),head.next为NULL。我无法弄清楚这段代码的逻辑有什么问题。

编辑1:我已经像这样初始化了头部(在主要部分):

struct SR head;

    head.ID = -1;
    head.next = NULL;
    head.ID = 0;head.GPA = 0;head.numCredits = 0;head.numCoursesTakenSoFar = 0; 
    head.GPApoints = 0;

从另一个从main调用的函数调用此函数:

我这样调用了这个函数:

ind_1 = findDuplicate ( first, a ); 

ind_1被声明为指向结构的指针。

调用findDuplicate的函数是processInput函数,因此a是一个从文本文件中读入学生ID的变量。

编辑2:从main我调用一个名为processInput的函数,它的一部分看起来像这样(直到第一次调用findDuplicate):

void processInput ( struct SR *first, char str [50] )
{
    char ch;    
    int a, b, x=0;
    struct SR *ind_1;
    FILE *fp;               
    fp = fopen ( str, "r" );
    if ( fp == NULL )
    {       printf("Can't open file\n");            
        exit ( 1 );                                 
    }
    while ( fscanf ( fp, "%d %d %c", &a, &b, &ch ) != EOF )     
    {
        ind_1 = findDuplicate ( first, a );         

从main开始,processInput被调用如下:

processInput ( &head, argv [i+1] );

我希望这是足够的信息。该程序真的很长,我不想放太多代码。因此,first是指向head的指针,head的地址从main传递给processInput。

2 个答案:

答案 0 :(得分:0)

所以问题可能是这个。

基本上看头只是指向某个内存位置的指针。您必须确保head指向链接列表的合法节点。如果head为NULL,则head-> id或temp-> id将非法生成核心转储。还要注意temp也只是一个指针,你不需要malloc它。简单地指出它。 见下文:



struct SR *findDuplicate ( struct SR *head, int ID )
    {
        struct SR *temp = NULL; // Pointer 4 bytes
        
        temp = head; // Assign value(address) of head to temp
        while ( temp && temp->ID != ID ) // Check if temp is NULL first
        {
            if ( temp->next != NULL )
            {
                temp = temp->next;
            }
            else 
            return NULL;
        }
        return temp;
    }




答案 1 :(得分:0)

正如其他人所评论的那样,你在代码中从malloc中泄漏了内存。

这就是说,运行你的示例代码如下并不会让我崩溃。为了说清楚,我不认为findDuplicate的这个实现是好的(它泄漏了内存,而且它过于冗长)。但是它本身并不正确(尽管存在内存泄漏):你为指针分配空间,设置指针,然后取消引用该指针。

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

struct SR {
    struct SR *next;
    int ID;
};

struct SR *findDuplicate ( struct SR *head, int ID )
{
    struct SR *temp = NULL;
    temp = malloc ( sizeof ( head ) );
    temp = head;
    while ( temp->ID != ID )
    {
        if ( temp->next != NULL )
        {
            temp = temp->next;
        }
        else
            return NULL;
    }
    return temp;
}

int main(int argc, char **argv)
{
    struct SR head = { .next = NULL, .ID = -1 };
    struct SR *found = findDuplicate(&head, 42);
    free(found);
    return 0;
}

因此我建议你的processInput片段中的while循环可能是罪魁祸首。如果findDuplicate返回NULL,我想你正在用'first'做一些事情,这可能会破坏列表。

我认为你可能需要在程序中检查你的内存处理方法。我不明白为什么findDuplicate需要分配内存 - 如果findDuplicate在链表上没有找到ID的现有条目,我会预期分配struct SR的内存。

如果您发布完整的示例代码和输入数据,将有助于缩小您的确切问题。