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

时间:2021-12-18 07:18:39

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. 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. However somewhere in the populate method a segmentation fault error occurs. I am working with three files list_demo.c, linked_list.h and linked_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. 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. I even deleted the function and tried to populate it in main, but nothing works. 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.

所以我试图使用指向MonsterAttacks结构的指针作为属于链表的元素的数据。为了做到这一点,我尝试填充MonsterAttacks的结构,然后将其与null ptr一起传递给名为create的函数的下一个节点。然而,在填充方法中的某处,发生分段错误错误。我正在使用三个文件list_demo.c,linked_list.h和linked_list.c。我将构建构成一个功能齐全的链表的所有函数,希望我能在得到这个错误后尽快完成。处理这个错误大约两天,我向我的教授展示,他无法弄清楚为什么会发生这种情况,它似乎来自于填充功能。我试图返回指向一个支柱的指针,在这种情况下我得到一个总线错误,我已经尝试了几乎所有获取输入并将其存储在支柱上的变化。我甚至删除了该函数,并尝试在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

// 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上运行

2 个解决方案

#1


2  

new_node->monsterAttack->attackID = 0;

Allocating memory for new_node does not allocate memory for the MonsterAttacks struct inside it. That is why dereferencing monsterAttack to get its attackID is causing a seg fault.

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

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;
}

#2


0  

Edit: @bruceg pointed out the lack of semicolon, this malloc isn't the issue. @lightalchemist have highlighted that the second one is the fault.

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

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

Your malloc call is wrong, malloc allocates and returns a pointer to the memory. You ignore/discard the pointer value.

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

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));

#1


2  

new_node->monsterAttack->attackID = 0;

Allocating memory for new_node does not allocate memory for the MonsterAttacks struct inside it. That is why dereferencing monsterAttack to get its attackID is causing a seg fault.

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

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;
}

#2


0  

Edit: @bruceg pointed out the lack of semicolon, this malloc isn't the issue. @lightalchemist have highlighted that the second one is the fault.

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

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

Your malloc call is wrong, malloc allocates and returns a pointer to the memory. You ignore/discard the pointer value.

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

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));