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

时间:2018-09-21 02:18:45

标签: c pointers struct linked-list

因此,我尝试使用指向MonsterAttacks结构的指针作为属于链表元素的数据。为此,我尝试填充MonsterAttacks的结构,然后将其与空ptr一起传递给名为create的函数的下一个节点。但是,在populate方法中的某处会发生分段错误错误。我正在使用三个文件list_demo.clinked_list.hlinked_list.c。我将构建构成一个功能齐全的链表的所有功能,希望我能尽快通过此错误。处理此错误大约两天了,我向我的教授展示了,他不知道为什么会发生,它似乎来自populate函数。我试图返回一个指向Strut的指针,在这种情况下,我会遇到总线错误,并且尝试了几乎所有获取输入并将其存储在Strut上的变化。我什至删除了该函数并尝试将其填充到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编译器在Red Hat上运行的顺便说一句

2 个答案:

答案 0 :(得分:3)

new_node->monsterAttack->attackID = 0;

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

最少的有效代码

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

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

答案 1 :(得分:-1)

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

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

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

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

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