Почему возникает ошибка во время выполнения при использовании string в struct

#c #string #struct

#c #строка #struct

Вопрос:

Подробные сведения-

Я принимаю входные данные от n студентов

Их номер- rollno./ mobile / UID в объединении, их полное имя, название их курса, их возраст, название их филиала.

Я использую связанный список для хранения данных в отсортированном виде. Как только я вставляю узел, список сортируется одновременно. В конце я печатаю весь список. Список отсортирован по возрасту кандидатов.

Может кто-нибудь, пожалуйста, помочь мне, почему я получаю ошибку во время выполнения при вводе строки в этой программе. Что я должен исправить, чтобы программа не выдавала ошибку во время выполнения. Заранее спасибо.

 #include<bits/stdc  .h>
using namespace std;
typedef struct Node node;
struct Node
{
    union number
    {
        string roll;
        long long int mobile;
        string other;
    }id;
    string name;
    string course;
    int age;
    string branch;
    node *next;
    int type;
};
node *head=NULL;
int main()
{
    int n;
    cout<<"Enter the number of students: ";
    cin>>n;
    char ch;
    string roll;
    for(int i=1;i<=n;i  )
    {
        node *temp=(node*)(malloc(sizeof(node)));
        cin>>ch;
        if(ch=='R')
        {
            cin>>temp->id.roll;
            temp->type=0;
        }
        else if(ch=='M')
        {
            cin>>temp->id.mobile;
            temp->type=1;
        }
        else if(ch=='O')
        {
            cin>>temp->id.other;
            temp->type=2;
        }
        getline(cin,temp->name);
        getline(cin,temp->course);
        cin>>temp->age;
        getline(cin,temp->branch);

        if(head==NULL)
        {
            head=temp;
            head->next=NULL;
            continue;
        }
        if(head->age>=temp->age)
        {
            temp->next=head;
            head=temp;
            continue;
        }
        node *ptr;
        ptr=head;
        while((ptr->next)!=NULLamp;amp;(ptr->next)->age<temp->age)
        {
            ptr=ptr->next;
        }
        temp->next=ptr->next;
        ptr->next=temp;
    }
    node *ptr;
    ptr=head;
    while(ptr!=NULL)
    {
        if(ptr->type==0)
        {
            cout<<ptr->id.roll<<",";
        }
        else if(ptr->type==1)
        {
            cout<<ptr->id.mobile<<",";
        }
        else if(ptr->type==2)
        {
            cout<<ptr->id.other<<",";
        }
        cout<<ptr->name<<","<<ptr->course<<","<<ptr->age<<","<<ptr->branch<<endl;
        ptr=ptr->next;
    }
}
  

Ответ №1:

Первое, что вы должны сделать, это заменить

    node *temp=(node*)(malloc(sizeof(node)));
  

с

    node *temp=new node;
  

Не используйте malloc в программе на C . Причина в том, что malloc не вызывает конструкторы для объектов, которые он выделяет. std::string имеет конструктор, и его необходимо вызвать, иначе вы получите ошибки.

Второе, что вы должны сделать, это заменить объединение. Когда у объектов есть конструкторы, их сложно поместить в объединение. Причина в том, что только один объект в объединении активен в любой момент времени, так какой объект был создан? C позволяет вам размещать объекты с конструкторами в объединениях, но тогда вы должны обрабатывать построение таких объектов самостоятельно. Это довольно сложная тема, и я бы посоветовал просто удалить объединение и поместить roll , mobile и other непосредственно в node структуру. Но если вы хотите провести некоторое исследование, вам следует изучить std::variant , это замена объединения, или посмотрите на размещение new, это метод для ручного построения объектов.

Комментарии:

1. Большое спасибо :), но в вопросе, который меня попросили сделать с union, вот почему у меня возникли сомнения. Если я использую массив символов фиксированного размера, скажем, 20 вместо string , это дает правильный ответ, но тогда я не могу принимать string в качестве входных данных с пробелами между ними. Работает только строка без пробела.

2. @aman Я думаю, вы, должно быть, пропустили суть моего ответа. Как я уже объяснял, при объединении вы должны самостоятельно управлять построением объектов в объединении. Массив символов не имеет конструктора, но string имеет. Таким образом, помещая строку в объединение, вы даете себе дополнительную работу. Вы можете заставить это работать, но вам нужно будет использовать новую технику размещения, о которой я упоминал. Более простым вариантом было бы использовать std::variant . Еще более простым вариантом было бы вообще не использовать объединение.