C - 使用 malloc 时程序崩溃
C - Program crashes while using malloc
所以我正在制作一个 XOR 链表,每当我尝试为新节点分配内存时,程序就会崩溃。这是我的插入函数代码:
void add(DataType value, XORList ** xlist)
{
XORListNode * node;
node = ( XORListNode* )malloc( sizeof (XORListNode) );
printf("node memory allocated\n");
if ((*xlist)->head->prevPNext == NULL && (*xlist)->tail->prevPNext == NULL) //XOR linked list is empty: [ H - T ] + N => [ H<->T<->N ] => [ H<->A<->T ]
{
node->prevPNext = (*xlist)->tail; //new element points to tail
(*xlist)->tail->prevPNext = ( XORListNode * )( (uintptr_t)(*xlist)->head ^ (uintptr_t)(*xlist)->tail ); //tail points to head and new value
(*xlist)->head->prevPNext = (*xlist)->tail;
(*xlist)->tail->value = value;
(*xlist)->tail = node;
}
else //Otherwise: [ H<->A<->B<-...->X<->T ] + N => [ H<->A<->B<-...->X<->T<->N ] => [ H<->A<->B<-...->X<->Y<->T ]
{
node->prevPNext = (*xlist)->tail;
(*xlist)->tail->prevPNext = ( XORListNode * )( (uintptr_t)(*xlist)->tail->prevPNext ^ (uintptr_t)node );
(*xlist)->tail->value = value;
(*xlist)->tail = node;
}
}
这是 XORList 的定义:
typedef struct XORList
{
XORListNode * head, * tail;
} XORList;
这是 XORListNode 的定义:
typedef struct XORListNode
{
DataType value;
struct XORListNode * prevPNext;
} XORListNode;
我也非常感谢有关代码的任何其他评论,因为我还没有使用指针的经验。
感谢您的帮助。
malloc
不是你实现的问题。您可以通过删除除前三行之外的整个函数体来测试它。
正如 Sourav Ghosh 指出的那样,主要问题是您在使用它们之前不检查 xlist
、*xlist
、(*xlist)->head
或 (*xlist)->tail
是否为 NULL if 子句中的指针 if ((*xlist)->head->prevPNext == NULL && (*xlist)->tail->prevPNext == NULL)
.
所以如果你有一个 "uninitialized" 列表 head
和 tail
将是 NULL
(或者如果你没有将它们设置为 NULL
他们将是一些值,如 0xcccccccc
或完全未定义的值)导致访问冲突,因为您正在尝试访问您的应用程序不可用的地址。
要解决此问题,您必须在添加函数中处理以下情况:
void add(DataType value, XORList ** xlist)
{
XORListNode * node;
if ((xlist == NULL) || ((*xlist) == NULL))
{
printf("INVALID INPUT (xlist)\n");
return;
}
node = ( XORListNode* )malloc( sizeof (XORListNode) );
if (node == NULL) // always check return values
{
printf("FAILED TO ALLOCATE !!!\n");
return;
}
if (((*xlist)->head != NULL) && ((*xlist)->tail != NULL))
{
/* your current implementation goes here */
}
else
{
/*
** no item within list, yet!
** - initialize head and tail attributes of *xlist
** - set node->prevPNext to NULL
*/
}
}
还有三件事:
- 我强烈建议为您的
XORList
结构实现零函数,以确保 head
和 tail
成员为 NULL。否则它们未初始化并且检查它们是否为 NULL 将不起作用并且您再次遇到访问冲突。
- 为什么在函数
add
中使用指向XORList
的双指针?对于您发布的代码,一个指针就足够了。
- 由于
malloc
在某些情况下可能会失败,因此您应该为函数 add
实现一个 return 值。否则调用者无法知道添加是否成功。我会简单地 return node
的值。如果函数失败,return 值为 NULL
或非零值(如果成功)。
所以我正在制作一个 XOR 链表,每当我尝试为新节点分配内存时,程序就会崩溃。这是我的插入函数代码:
void add(DataType value, XORList ** xlist)
{
XORListNode * node;
node = ( XORListNode* )malloc( sizeof (XORListNode) );
printf("node memory allocated\n");
if ((*xlist)->head->prevPNext == NULL && (*xlist)->tail->prevPNext == NULL) //XOR linked list is empty: [ H - T ] + N => [ H<->T<->N ] => [ H<->A<->T ]
{
node->prevPNext = (*xlist)->tail; //new element points to tail
(*xlist)->tail->prevPNext = ( XORListNode * )( (uintptr_t)(*xlist)->head ^ (uintptr_t)(*xlist)->tail ); //tail points to head and new value
(*xlist)->head->prevPNext = (*xlist)->tail;
(*xlist)->tail->value = value;
(*xlist)->tail = node;
}
else //Otherwise: [ H<->A<->B<-...->X<->T ] + N => [ H<->A<->B<-...->X<->T<->N ] => [ H<->A<->B<-...->X<->Y<->T ]
{
node->prevPNext = (*xlist)->tail;
(*xlist)->tail->prevPNext = ( XORListNode * )( (uintptr_t)(*xlist)->tail->prevPNext ^ (uintptr_t)node );
(*xlist)->tail->value = value;
(*xlist)->tail = node;
}
}
这是 XORList 的定义:
typedef struct XORList
{
XORListNode * head, * tail;
} XORList;
这是 XORListNode 的定义:
typedef struct XORListNode
{
DataType value;
struct XORListNode * prevPNext;
} XORListNode;
我也非常感谢有关代码的任何其他评论,因为我还没有使用指针的经验。
感谢您的帮助。
malloc
不是你实现的问题。您可以通过删除除前三行之外的整个函数体来测试它。
正如 Sourav Ghosh 指出的那样,主要问题是您在使用它们之前不检查 xlist
、*xlist
、(*xlist)->head
或 (*xlist)->tail
是否为 NULL if 子句中的指针 if ((*xlist)->head->prevPNext == NULL && (*xlist)->tail->prevPNext == NULL)
.
所以如果你有一个 "uninitialized" 列表 head
和 tail
将是 NULL
(或者如果你没有将它们设置为 NULL
他们将是一些值,如 0xcccccccc
或完全未定义的值)导致访问冲突,因为您正在尝试访问您的应用程序不可用的地址。
要解决此问题,您必须在添加函数中处理以下情况:
void add(DataType value, XORList ** xlist)
{
XORListNode * node;
if ((xlist == NULL) || ((*xlist) == NULL))
{
printf("INVALID INPUT (xlist)\n");
return;
}
node = ( XORListNode* )malloc( sizeof (XORListNode) );
if (node == NULL) // always check return values
{
printf("FAILED TO ALLOCATE !!!\n");
return;
}
if (((*xlist)->head != NULL) && ((*xlist)->tail != NULL))
{
/* your current implementation goes here */
}
else
{
/*
** no item within list, yet!
** - initialize head and tail attributes of *xlist
** - set node->prevPNext to NULL
*/
}
}
还有三件事:
- 我强烈建议为您的
XORList
结构实现零函数,以确保head
和tail
成员为 NULL。否则它们未初始化并且检查它们是否为 NULL 将不起作用并且您再次遇到访问冲突。 - 为什么在函数
add
中使用指向XORList
的双指针?对于您发布的代码,一个指针就足够了。 - 由于
malloc
在某些情况下可能会失败,因此您应该为函数add
实现一个 return 值。否则调用者无法知道添加是否成功。我会简单地 returnnode
的值。如果函数失败,return 值为NULL
或非零值(如果成功)。