C语言 为什么在尝试填充结构时出现分段错误(核心转储)或总线错误(核心转储)?



所以我试图使用指向MonsterAttacks结构的指针作为属于链表元素的数据。为了做到这一点,我尝试填充一个MonsterAttacks的结构,然后将其与空 ptr 一起传递给一个名为 create 的函数的下一个节点。但是,在populate方法中的某个地方会发生分段错误。我正在使用三个文件list_demo.clinked_list.hlinked_list.c。我将构建构成功能齐全的链表的所有函数,希望我能在通过此错误后尽快完成。处理这个错误大约两天了,我向我的教授展示了,他无法弄清楚为什么会发生,它似乎来自populate函数。我试图返回指向支柱的指针,在这种情况下我得到总线错误,并且我已经尝试了几乎所有获取输入并将其存储在支柱上的变体。我什至删除了该功能并尝试在 main 中填充它,但没有任何效果。我是 C 的新手,我的教授帮助我调试了大约一个小时,他最终放弃了,所以任何帮助将不胜感激。

list_demo.c

#include <stdio.h>
#include "linked_list.h"
#include <stdlib.h>

void populate(struct MonsterAttacks *m){
printf("Enter the name for the Monster n");
scanf("%40s",m->monsterName);
puts("What is his/her attack location?");
scanf("%40s",m->attackLocation);
puts("What are the number of victims this monster has demolished?");
scanf("%ud", &m->numOfVictims);      
m->attackID = 0;
}
int main(void)
{
node* tmp = NULL;
struct MonsterAttacks *tmpMonst = (struct MonsterAttacks *) 
malloc(sizeof(struct MonsterAttacks));
if(tmpMonst == NULL){
printf("Error allocating memory");
}
else
populate(tmpMonst);
node *head = create(tmpMonst,tmp);
free(tmpMonst);
return 0;
}

linked_list.h

#ifndef LINKED_LIST
#define LINKED_LIST

typedef struct node{
struct MonsterAttacks *monsterAttack;
struct node* next;
} node;

struct MonsterAttacks{
unsigned int attackID;
char monsterName[41];
char attackLocation[41];
unsigned int numOfVictims;
};
/*
create a new node
initialize the data and next field
return the newly created node
*/
node* create(struct MonsterAttacks *m,node* next);

#endif

linked_list.c

来自 zentut.com,大量改编

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "linked_list.h" 

/*
create a new node
initialize the data and next field
return the newly created node
*/
node* create(struct MonsterAttacks *m,node* next)
{
node* new_node = (node*)malloc(sizeof(node));
if(new_node == NULL)
{
printf("Error creating a new node.n");
exit(0);
}
new_node->monsterAttack->attackID = 0;
new_node->next = next;
strncpy(new_node->monsterAttack->monsterName,m->monsterName,41);
strncpy(new_node->monsterAttack->attackLocation, m->attackLocation, 41);
new_node->monsterAttack->numOfVictims = m->numOfVictims;
return new_node;
}

顺便说一句,使用 gcc 编译器在红帽上运行

new_node->monsterAttack->attackID = 0;

new_node分配内存不会为其内部的MonsterAttacks结构分配内存。这就是为什么取消引用monsterAttack以获取其attackID会导致 seg 错误的原因。

最少的工作代码

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
// Moved the two structs out to make a minimal reproducible code
/*  #include "linked_list.h" */
struct MonsterAttacks{
unsigned int attackID;
char monsterName[41];
char attackLocation[41];
unsigned int numOfVictims;
};
typedef struct node{
struct MonsterAttacks *monsterAttack;
struct node* next;
} node;
void populate(struct MonsterAttacks *m){
printf("Enter the name for the Monster n");
scanf("%40s",m->monsterName);
puts("What is his/her attack location?");
scanf("%40s",m->attackLocation);
puts("What are the number of victims this monster has demolished?");
scanf("%ud", &m->numOfVictims);      
m->attackID = 0;
}
node* create(struct MonsterAttacks *m,node* next)
{
node* new_node = (node*)malloc(sizeof(node));
if(new_node == NULL)
{
printf("Error creating a new node.n");
exit(0);
}
// Just add this line
new_node->monsterAttack = malloc(sizeof (struct MonsterAttacks));
new_node->monsterAttack->attackID = 0;
new_node->next = next;
strncpy(new_node->monsterAttack->monsterName,m->monsterName,41);
strncpy(new_node->monsterAttack->attackLocation, m->attackLocation, 41);
new_node->monsterAttack->numOfVictims = m->numOfVictims;
return new_node;
}
int main(void)
{
node* tmp = NULL;
struct MonsterAttacks *tmpMonst = (struct MonsterAttacks *) 
malloc(sizeof(struct MonsterAttacks));
if(tmpMonst == NULL){
printf("Error allocating memory");
}
else {
populate(tmpMonst);
}
node *head = create(tmpMonst,tmp);
printf("Name: %sn", tmpMonst->monsterName);
printf("num victim: %dn", tmpMonst->numOfVictims);
free(tmpMonst);
return 0;
}

create(...)中为new_node分配内存时,在堆上为类型node的结构分配内存以保存它包含的所有变量。在这种情况下,node中的monsterAttack最初是指向无处的结构的指针。您需要为要指向的指针monsterAttack显式分配内存。

编辑:@bruceg指出缺少分号,但这个malloc不是问题。 @lightalchemist强调第二个是错误。

struct MonsterAttacks *tmpMonst = (struct MonsterAttacks *);
malloc(sizeof(struct MonsterAttacks));

您的malloc调用是错误的,malloc 分配并返回指向内存的指针。忽略/丢弃指针值。

后面的代码似乎假设tmpMonst指向这个分配的内存,但两者之间没有链接。

试试struct MonsterAttacks *tmpMonst = malloc(sizeof(struct MonsterAttacks));

最新更新