简体   繁体   English

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

[英]Why am I getting Segmentation fault (core dumped) or bus error (core dumped) when trying to populate a struct?

So I am trying to use a pointer to a struct of MonsterAttacks as the data that belongs to an element of a linked list. 因此,我尝试使用指向MonsterAttacks结构的MonsterAttacks作为属于链表元素的数据。 In order to do this I try to populate a struct of MonsterAttacks and then pass that along with a null ptr to a next node to a function called create. 为此,我尝试填充MonsterAttacks的结构,然后将其与空ptr一起传递给名为create的函数的下一个节点。 However somewhere in the populate method a segmentation fault error occurs. 但是,在populate方法中的某处会出现分段错误错误。 I am working with three files list_demo.c , linked_list.h and linked_list.c . 我正在处理三个文件list_demo.clinked_list.hlinked_list.c I will build all the the functions that make up a fully functioning linked list, well hoping I can as soon as I get pass this error. 我将构建构成一个功能齐全的链表的所有功能,希望我能尽快通过此错误。 Been dealing with this error for about two days and I showed my professor and he could not figure out why its happening, it seems to come from the populate function. 处理这个错误大约两天了,我向我的教授展示了,他不知道为什么会发生,它似乎来自于populate函数。 I have tried to return a pointer to a strut in which case I get a bus error, and I have tried almost every variation of getting input and storing it on the strut. 我试图返回一个指向Strut的指针,在这种情况下,我会遇到总线错误,并且尝试了几乎所有获取输入并将其存储在Strut上的变化。 I even deleted the function and tried to populate it in main, but nothing works. 我什至删除了该函数并尝试将其填充到main中,但没有任何效果。 I am new to C and my professor helped me out for about an hour debug this problem and he finally gave up, so any help would be appreciated. 我刚接触C,我的教授帮助我解决了大约一个小时的问题,他终于放弃了,因此对您的帮助将不胜感激。

list_demo.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 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 linked_list.c

// from zentut.com, heavily adapted //从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;
}

Btw running on Red Hat using gcc compiler 使用gcc编译器在Red Hat上运行的Btw

new_node->monsterAttack->attackID = 0;

Allocating memory for new_node does not allocate memory for the MonsterAttacks struct inside it. new_node分配内存不会为其内部的MonsterAttacks结构分配内存。 That is why dereferencing monsterAttack to get its attackID is causing a seg fault. 这就是为什么取消引用monsterAttack以获取其attackID会导致段错误的原因。

A minimal working code 最小的工作代码

#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: %s\n", tmpMonst->monsterName);
    printf("num victim: %d\n", tmpMonst->numOfVictims);

    free(tmpMonst);
    return 0;
}

When you allocate memory for new_node in create(...) , you allocate memory on the heap for a structure of type node to hold all the variables it contains. create(...)new_node分配内存时,会在堆上为类型为node的结构分配内存,以容纳它包含的所有变量。 In this case, monsterAttack in node is initially a pointer to a struct that is pointing to nowhere. 在这种情况下, monsterAttacknode最初为指针,是指向无处一个结构。 You need to explicitly allocate memory for the monsterAttack pointer to point to. 您需要为monsterAttack指针明确分配内存。

Edit : @bruceg pointed out the lack of semicolon, this malloc isn't the issue. 编辑 :@bruceg指出缺少分号,这不是问题。 @lightalchemist have highlighted that the second one is the fault. @lightalchemist强调第二个是错误。

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

Your malloc call is wrong, malloc allocates and returns a pointer to the memory. 您的malloc调用是错误的,malloc分配并返回指向内存的指针。 You ignore/discard the pointer value. 您忽略/放弃指针值。

Later code seems to assume that tmpMonst points to this allocated memory but there is no link between the two. 后面的代码似乎假定tmpMonst指向此分配的内存,但两者之间没有链接。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM