C-链表中的分割错误



我知道当您尝试访问程序范围之外的内存时会发生设置错误,但我无法弄清楚我的内存在哪里发生,或者为什么。我定义了一个列表: *列表类型列表 = 空; ,然后我将数据添加到调用 main 中的 add 函数的列表中: addNodeToList(&list, song(;

void addNodeToList(ListType **list, SongType *song)
{
    printf("Starting Add");
    NodeType *newNode = malloc(sizeof(NodeType));
    NodeType *currNode;
    currNode = (*list)->head;
    newNode->data = song;
    newNode->next = NULL;
    if(currNode == NULL) {
        printf("List is Empty");
        (*list)->tail = newNode;
        (*list)->head = newNode;
    }
    else {
        (*list)->tail->next = newNode;
        (*list)->tail = newNode;
    }
}

正在传递的歌曲已正确初始化,我可以访问它的元素,所以我知道这不会导致 seg 错误。任何帮助将不胜感激!

typedef struct Song {
  char title[MAX_STR];
  char artist[MAX_STR];
  char album[MAX_STR];
  char duration[MAX_STR];
} SongType;
typedef struct Node {
  struct Node *next;
  SongType *data;
} NodeType;
typedef struct List {
  NodeType *head;
  NodeType *tail;
} ListType;

main中,如果你声明

 ListType* list = NULL;

然后在你的函数中调用

 (*list)->head

取消引用(*list)很好,但是一旦你这样做->head它就会尝试取消引用原始NULL分配。 您需要先为list分配一些空间。

您的调用代码似乎包含:

ListType *list = NULL;

你像这样调用你的函数:

addNodeToList(&list, song);

在您的addNodeToList()函数中,您有:

NodeType *currNode;
currNode = (*list)->head;

这意味着您正在取消引用空指针(*list),这会使您的代码崩溃。 至少,在设置currNode之前检查是否*list == NULL,但您需要重新考虑代码以处理list为空指针的情况。

此代码编译并运行。 它通过在必要时分配列表来避免此问题:

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
enum { MAX_STR = 64 };
typedef struct Song
{
    char title[MAX_STR];
    char artist[MAX_STR];
    char album[MAX_STR];
    char duration[MAX_STR];
} SongType;
typedef struct Node
{
    struct Node *next;
    SongType *data;
} NodeType;
typedef struct List
{
    NodeType *head;
    NodeType *tail;
} ListType;
void addNodeToList(ListType **list, SongType *song);
void addNodeToList(ListType **list, SongType *song)
{
    printf("Starting Addn");
    assert(list != NULL);
    if (*list == NULL)
    {
        *list = malloc(sizeof(**list));
        assert(*list != 0);  // Too lazy for production
        (*list)->head = 0;
        (*list)->tail = 0;
        printf("List createdn");
    }
    NodeType *newNode = malloc(sizeof(NodeType));
    newNode->data = song;
    newNode->next = NULL;
    printf("Node createdn");
    NodeType *currNode = (*list)->head;
    if (currNode == NULL)
    {
        printf("List is Emptyn");
        (*list)->tail = newNode;
        (*list)->head = newNode;
    }
    else
    {
        (*list)->tail->next = newNode;
        (*list)->tail = newNode;
    }
    printf("Node added - all donen");
}

int main(void)
{
    ListType *list = NULL;
    SongType  data = { "Title", "Artist", "Album", "2m 30s" };
    SongType *song = &data;
    printf("Add song oncen");
    addNodeToList(&list, song);
    printf("Add song againn");
    addNodeToList(&list, song);
    return 0;
}

示例运行:

Add song once
Starting Add
List created
Node created
List is Empty
Node added - all done
Add song again
Starting Add
Node created
Node added - all done

代码像筛子一样泄漏;没有释放内存。

问题涉及此语句

ListType *list = NULL;

您不能为以这种方式初始化的列表调用addNodeToList。否则将出现未定义的行为。

应按以下方式声明列表

ListType list = { NULL, NULL };

此外,函数addNodeToList可以声明更简单

void addNodeToList(ListType *list, SongType *song);
                   ^^^^^^^^^^^^^^ 

你可以这样称呼它

addNodeToList( &list, song );

例如

void addNodeToList( ListType *list, SongType *song )
{
    printf("Starting Add");
    NodeType *newNode = malloc( sizeof( NodeType ) );
    if ( newNode != NULL )
    {
        newNode->data = song;
        newNode->next = NULL;
        if ( list->tail == NULL )
        {
            printf( "List is Emptyn" );
            list->head = list->tail = newNode;
        }
        else
        {
            list->tail->next = newNode;
            list->tail = newNode;
        }
    }
}

或者如果你想有一个指向列表的指针,那么你应该写

ListType *list = malloc( sizeof( ListType ) );
list->head = list-tail = NULL;;

然后调用我按以下方式显示的函数的定义

addNodeToList( list, song );

相关内容

  • 没有找到相关文章

最新更新