我理解当您尝试访问程序范围之外的内存时会发生设置错误,但我无法弄清楚我的发生位置或原因。我有一个列表定义: * ListType list = NULL; , 然后我将数据添加到List中,调用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;
答案 0 :(得分:3)
main
中
ListType* list = NULL;
然后在你的功能中你打电话
(*list)->head
解除引用(*list)
没问题,但是只要你->head
它尝试取消引用原始NULL
作业就行了。您需要先为list
分配一些空间。
答案 1 :(得分:1)
您的主叫代码似乎包含:
ListType *list = NULL;
你打电话给你的函数:
addNodeToList(&list, song);
并在您的addNodeToList()
函数中:
NodeType *currNode;
currNode = (*list)->head;
这意味着您将取消引用空指针(*list)
,这会导致代码崩溃。至少,在设置*list == NULL
之前检查是否currNode
,但是您需要重新考虑代码以处理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 Add\n");
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 created\n");
}
NodeType *newNode = malloc(sizeof(NodeType));
newNode->data = song;
newNode->next = NULL;
printf("Node created\n");
NodeType *currNode = (*list)->head;
if (currNode == NULL)
{
printf("List is Empty\n");
(*list)->tail = newNode;
(*list)->head = newNode;
}
else
{
(*list)->tail->next = newNode;
(*list)->tail = newNode;
}
printf("Node added - all done\n");
}
int main(void)
{
ListType *list = NULL;
SongType data = { "Title", "Artist", "Album", "2m 30s" };
SongType *song = &data;
printf("Add song once\n");
addNodeToList(&list, song);
printf("Add song again\n");
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
代码漏像筛子;没有记忆被释放。
答案 2 :(得分:0)
问题涉及此声明
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 Empty\n" );
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 );