Почему при заполнении структуры возникает ошибка сегментации (сбрасывается ядро) или ошибки шины (сбрасывается ядро)? - PullRequest
0 голосов
/ 21 сентября 2018

Поэтому я пытаюсь использовать указатель на структуру MonsterAttacks в качестве данных, принадлежащих элементу связанного списка.Чтобы сделать это, я пытаюсь заполнить структуру MonsterAttacks, а затем передать ее вместе с нулевым ptr следующему узлу в функцию с именем create.Однако где-то в методе populate возникает ошибка ошибки сегментации.Я работаю с тремя файлами list_demo.c, linked_list.h и linked_list.c.Я создам все функции, которые составляют полностью функционирующий связанный список, надеясь, что смогу, как только получу эту ошибку.Занимался этой ошибкой около двух дней, и я показал своему профессору, а он не мог понять, почему это происходит, похоже, это происходит из функции populate.Я попытался вернуть указатель на стойку, и в этом случае я получил ошибку шины, и я попробовал почти все варианты получения ввода и сохранения его в стойке.Я даже удалил функцию и попытался заполнить ее в основном, но ничего не работает.Я новичок в 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;
}

connected_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

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

Кстати, на Red Hat с использованием компилятора gcc

Ответы [ 2 ]

0 голосов
/ 21 сентября 2018
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, чтобы он указывал на

.
0 голосов
/ 21 сентября 2018

Редактировать : @bruceg указал на отсутствие точки с запятой, этот malloc не проблема.@lightalchemist подчеркнул, что второй является ошибкой.

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

Ваш malloc вызов неверен, malloc выделяет и возвращает указатель на память.Вы игнорируете / отбрасываете значение указателя.

Более поздний код, кажется, предполагает, что tmpMonst указывает на эту выделенную память, но между ними нет связи.

Попробуйте struct MonsterAttacks *tmpMonst = malloc(sizeof(struct MonsterAttacks));

...