C Segmentation Fault (core dumped) 链表
C Segmentation Fault (core dumped) Linked List
我一直收到 Segmentation Fault (core dumped)
运行 时间错误,我不知道为什么。
我的代码:
struct Node
{
void *next;
void *val;
};
typedef struct Node* NodePtr;
struct List
{
NodePtr head;
};
typedef struct List* ListPtr;
ListPtr create()
{
ListPtr ptr = malloc(sizeof(struct List));
return ptr;
}
int insert(ListPtr list, void *obj)
{
NodePtr newObj = malloc(sizeof(struct Node));
//Cast next as a self referencing Node
newObj->next = (NodePtr) newObj->next;
//Point to beginning of list
NodePtr current = list->head;
if(list->head == NULL)
{
newObj->val = obj;
list->head->next = newObj;
newObj->next = NULL;
return 1;
}
return 0;
}
int main(int argc, char *argv[])
{
int x = 2;
int *p = &x;
ListPtr thing = create();
insert(thing, p);
return 0;
}
错误在这里:list->head->next = newObj
经过一些调试。我以为我必须为 list->head->next 分配内存,但是当我为此添加代码时,它仍然给了我同样的错误。我是投错了还是没有正确分配内存?任何帮助将不胜感激,谢谢!
您检查 list->head
是否为 NULL,然后对其进行一些操作。将其更改为 if(list->head != NULL)
{
...
}
一想,malloc 不保证分配的内存是空的。在分配后将所有值设置在重要的地方是一种很好的做法。
list->head 可能不为空
另外:newObj->next = (NodePtr) newObj->next;
没有设置为合理值,它设置为设置的任何内存 - 你打算 newObj->next = (NodePtr) newObj; ?
list->head 如果为 null,则不应引用。 list->head->next 只有在不为空时才有效。
如果你真的想建立一个列表,
newObj->val = obj;
if (list->head == NULL) { newObj->next = list->head; }
list->head = newObj;
或者沿着 list->head->next 链向下移动直到 next 为空,并将其设置为 newObj->next。如果那样的话,那可能是个好主意,newObj->next 应该设置为 NULL 而不是它本身。
可能想弄清楚您的列表的行为方式 - 它是循环的吗?它是从头部(list->head)还是尾部(last ->next)开始生长的?当 listObject->next == NULL 或 listObject->next == listObject 时,你发现尾巴了吗?
把它放在一起,运行良好。
#include <stdlib.h>
#include <stdio.h>
struct Node {
void *next;
void *val;
};
typedef struct Node* NodePtr;
struct List {
NodePtr head;
};
typedef struct List* ListPtr;
ListPtr CreateList() {
ListPtr ptr = malloc(sizeof(struct List));
return ptr;
}
void Insert(ListPtr list, void *obj) {
// create and initialize new node
NodePtr newObj = malloc(sizeof(struct Node));
newObj->val = obj;
newObj->next = NULL;
//Point to beginning of list
NodePtr curr = list->head;
// Add node to the list
if(curr == NULL) // if no head node, make newObj the head node
{
list->head = newObj;
}
else{ // otherwise traverse the list until you find the last node (the one that points to a null as the next)
while(1) {
if(curr->next != NULL) {
curr = curr -> next;
} else {
curr->next = newObj;
}
list->head = newObj;
newObj->val = obj;
list->head->next = newObj;
newObj->next = NULL;
}
}
}
int main() {
int x = 2;
int *p = &x;
ListPtr thing = CreateList();
Insert(thing, p);
return 0;
}
我意识到这个答案主要是风格化的。但我确实认为(坏)风格和(坏)习惯是(坏)编程的(重要)部分。总结一下...
- (在大多数情况下)不需要 typedef;他们只是为已经存在的东西引入了一个别名。
- [七规则] 人类 reader 可以跟踪的标识符 ("names") 数量有限。这可能是 7。尽量减少不同单词的数量使阅读更容易。
- 此外,reader 必须记住 xPtr 和 xNode 相关 (typeof *xPtr === typeof xNode)
- 阅读源代码时,关键字和特殊字符标记(如运算符)不要算作作为标识符,因为您不必记住它们。 (语法高亮也有帮助)
- 如果你的程序只有一种表达方式,就不可能出现像
iPtr *p; p = (qPtr) malloc (sizeof xNode);
这样的错误
- 创建另一个结构(+typedefs),只是为了容纳一个 root 指针会破坏你的精神命名空间。
现在对(预期的)代码进行返工:
#include <stdio.h>
#include <stdlib.h>
struct node {
struct node *next;
void *payload;
};
struct node *root=NULL;
void initialize() { /* nothing .... */ }
int insert(struct node **pp, void *pv) {
struct node *p;
p = malloc(sizeof *p);
if (!p) { /* handle error */ return -1; }
p->payload = pv;
p->next = *pp;
*pp = p;
return 1; /* inserted one element */
}
int main(void)
{
int i;
i=666;
/* note: this function call will pass a pointer to a local variable `i`
** to the insert() function, which will remember it.
** This is generally a bad idea, to say the least.
*/
insert( &root, &i);
return 0;
}
我一直收到 Segmentation Fault (core dumped)
运行 时间错误,我不知道为什么。
我的代码:
struct Node
{
void *next;
void *val;
};
typedef struct Node* NodePtr;
struct List
{
NodePtr head;
};
typedef struct List* ListPtr;
ListPtr create()
{
ListPtr ptr = malloc(sizeof(struct List));
return ptr;
}
int insert(ListPtr list, void *obj)
{
NodePtr newObj = malloc(sizeof(struct Node));
//Cast next as a self referencing Node
newObj->next = (NodePtr) newObj->next;
//Point to beginning of list
NodePtr current = list->head;
if(list->head == NULL)
{
newObj->val = obj;
list->head->next = newObj;
newObj->next = NULL;
return 1;
}
return 0;
}
int main(int argc, char *argv[])
{
int x = 2;
int *p = &x;
ListPtr thing = create();
insert(thing, p);
return 0;
}
错误在这里:list->head->next = newObj
经过一些调试。我以为我必须为 list->head->next 分配内存,但是当我为此添加代码时,它仍然给了我同样的错误。我是投错了还是没有正确分配内存?任何帮助将不胜感激,谢谢!
您检查 list->head
是否为 NULL,然后对其进行一些操作。将其更改为 if(list->head != NULL)
{
...
}
一想,malloc 不保证分配的内存是空的。在分配后将所有值设置在重要的地方是一种很好的做法。 list->head 可能不为空
另外:newObj->next = (NodePtr) newObj->next; 没有设置为合理值,它设置为设置的任何内存 - 你打算 newObj->next = (NodePtr) newObj; ?
list->head 如果为 null,则不应引用。 list->head->next 只有在不为空时才有效。
如果你真的想建立一个列表,
newObj->val = obj;
if (list->head == NULL) { newObj->next = list->head; }
list->head = newObj;
或者沿着 list->head->next 链向下移动直到 next 为空,并将其设置为 newObj->next。如果那样的话,那可能是个好主意,newObj->next 应该设置为 NULL 而不是它本身。
可能想弄清楚您的列表的行为方式 - 它是循环的吗?它是从头部(list->head)还是尾部(last ->next)开始生长的?当 listObject->next == NULL 或 listObject->next == listObject 时,你发现尾巴了吗?
把它放在一起,运行良好。
#include <stdlib.h>
#include <stdio.h>
struct Node {
void *next;
void *val;
};
typedef struct Node* NodePtr;
struct List {
NodePtr head;
};
typedef struct List* ListPtr;
ListPtr CreateList() {
ListPtr ptr = malloc(sizeof(struct List));
return ptr;
}
void Insert(ListPtr list, void *obj) {
// create and initialize new node
NodePtr newObj = malloc(sizeof(struct Node));
newObj->val = obj;
newObj->next = NULL;
//Point to beginning of list
NodePtr curr = list->head;
// Add node to the list
if(curr == NULL) // if no head node, make newObj the head node
{
list->head = newObj;
}
else{ // otherwise traverse the list until you find the last node (the one that points to a null as the next)
while(1) {
if(curr->next != NULL) {
curr = curr -> next;
} else {
curr->next = newObj;
}
list->head = newObj;
newObj->val = obj;
list->head->next = newObj;
newObj->next = NULL;
}
}
}
int main() {
int x = 2;
int *p = &x;
ListPtr thing = CreateList();
Insert(thing, p);
return 0;
}
我意识到这个答案主要是风格化的。但我确实认为(坏)风格和(坏)习惯是(坏)编程的(重要)部分。总结一下...
- (在大多数情况下)不需要 typedef;他们只是为已经存在的东西引入了一个别名。
- [七规则] 人类 reader 可以跟踪的标识符 ("names") 数量有限。这可能是 7。尽量减少不同单词的数量使阅读更容易。
- 此外,reader 必须记住 xPtr 和 xNode 相关 (typeof *xPtr === typeof xNode)
- 阅读源代码时,关键字和特殊字符标记(如运算符)不要算作作为标识符,因为您不必记住它们。 (语法高亮也有帮助)
- 如果你的程序只有一种表达方式,就不可能出现像
iPtr *p; p = (qPtr) malloc (sizeof xNode);
这样的错误
- 创建另一个结构(+typedefs),只是为了容纳一个 root 指针会破坏你的精神命名空间。
现在对(预期的)代码进行返工:
#include <stdio.h>
#include <stdlib.h>
struct node {
struct node *next;
void *payload;
};
struct node *root=NULL;
void initialize() { /* nothing .... */ }
int insert(struct node **pp, void *pv) {
struct node *p;
p = malloc(sizeof *p);
if (!p) { /* handle error */ return -1; }
p->payload = pv;
p->next = *pp;
*pp = p;
return 1; /* inserted one element */
}
int main(void)
{
int i;
i=666;
/* note: this function call will pass a pointer to a local variable `i`
** to the insert() function, which will remember it.
** This is generally a bad idea, to say the least.
*/
insert( &root, &i);
return 0;
}