【问题标题】:Segfault with linked lists in CC中带有链表的段错误
【发布时间】:2016-11-04 05:44:46
【问题描述】:

我正在为我当前的 CS 类编写一个涉及链表的程序,特别是一个函数在我调用它时会导致分段错误。函数如下:

void addSong(Playlist *theList, char *name, char *title, char *artist, int minutes, int seconds) {
    /*
        1. Make sure a playlist by that name exists (so you can add a song to it)
        2. Make sure the song does not already exist in the playlist (title/artist)
        3. Add the new song to the end of the songlist in that playlist (add-at-end)
    */
    Playlist *Pointer = theList;
    while(1){//Find the list
        if(strcmp(Pointer->name, name) == 0)
            break;
        if(Pointer->next == NULL){
            printf("There is no playlist by that name.\n");
            return;
        }
        Pointer = Pointer->next;
    }
    Song *playPoint = Pointer->songlist;
    while(1){//Find the end of the list
        if(playPoint == NULL){
            Song *Songy = malloc(sizeof(Song));
            Songy->title = title;
            Songy->artist = artist;
            Songy->minutes = minutes;
            Songy->seconds = seconds;
            Pointer->songlist = Songy;
        }
        if(strcmp(playPoint->title, title) == 0 && strcmp(playPoint->artist, artist) == 0){
            printf("There is already a song by that title and artist.");
            return;
        }
        if(playPoint->next == NULL){
            break;
        }
        playPoint = playPoint->next;
    }
    Song *Songy = malloc(sizeof(Song));
    Songy->title = title;
    Songy->artist = artist;
    Songy->minutes = minutes;
    Songy->seconds = seconds;
    playPoint->next = Songy;    //Add the song to the end of the list
    return;
}

如果重要的话,这里是引用的两个结构:

typedef struct song {
    char *title;
    char *artist;
    int minutes;
    int seconds;
    struct song *next;
} Song;

typedef struct playlist {
    char *name;
    Song *songlist;
    struct playlist *next;
} Playlist; 

我在做什么导致段错误?

【问题讨论】:

  • 你试过使用调试器吗?
  • 你应该把它分成两部分:一个找到播放列表,一个添加一首歌。这将更容易看出哪一个有问题,并且通常更清洁。您还可以将 struct song 作为参数传递,而不是单独传递其所有字段。
  • 发布后(没有主入口点),代码不会出现任何分段错误......
  • 无论如何,一个问题是你没有初始化你添加的歌曲的nexts。正如 MD XF 指出的那样,调试器在这里可以提供很大帮助;即使你不知道如何使用它来检查程序的状态,它至少会告诉你段错误发生在哪一行。

标签: c struct linked-list segmentation-fault


【解决方案1】:

您没有发布足够的信息以使某人能够准确地发现您的段错误发生的位置。考虑将其隔离在 MCVE example 中。

但是,当playPoint == NULL 在您的第二个 while 循环中时,肯定会发生段错误,因为您最终还是通过访问 playPoint->title 来使用它:

if(playPoint == NULL){
    Song *Songy = malloc(sizeof(Song));
    Songy->title = title;
    Songy->artist = artist;
    Songy->minutes = minutes;
    Songy->seconds = seconds;
    Pointer->songlist = Songy;
}
// here, playPoint is still equal to NULL!! COde from your if statement did not change that!
// accessing playPoint->title and playPoint->artist will crash for sure (seg fault)
if(strcmp(playPoint->title, title) == 0 && strcmp(playPoint->artist, artist) == 0){
    printf("There is already a song by that title and artist.");
    return;
}

你的意思可能是:

if(playPoint == NULL){
        playPoint = malloc(sizeof(Song));
        playPoint->title = title;
        playPoint->artist = artist;
        playPoint->minutes = minutes;
        playPoint->seconds = seconds;
        Pointer->songlist = playPoint;
}

但很难猜...

但此代码中可能存在其他段错误来源(例如 Songy->next 未设置,就像 Ryan 评论的那样)+ 在您未发布的其他代码中。

您可能在开始测试之前编写了太多代码,并且您可能有很多地方做错了并且可能导致段错误。考虑从头开始你的项目并通过迭代添加东西(测试和验证每次迭代)......或使用调试器来修复它们......

【讨论】:

    猜你喜欢
    • 2016-03-19
    • 2012-11-06
    • 2021-09-10
    • 1970-01-01
    • 1970-01-01
    • 2018-04-02
    • 2013-10-21
    • 2012-06-12
    • 2020-09-10
    相关资源
    最近更新 更多