我知道当您尝试访问程序范围之外的内存时会发生设置错误,但我无法弄清楚我的内存在哪里发生,或者为什么。我定义了一个列表: *列表类型列表 = 空; ,然后我将数据添加到调用 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 );