Получение неожиданного вывода при использовании массива в структуре

#c #struct

Вопрос:

Я новичок в мире программирования на c . Я получаю неожиданную вещь при запуске следующего кода:

 #include <iostream>
using namespace std;

typedef struct person
{
    int age;
    char* name;
    float salary;
    bool gender;
} prsn;

enum Gender
{
    male,
    female
};

int main()
{
    prsn p1;
    p1.name[0] = 'A';
    p1.name[1] = 'd';
    p1.name[2] = 'i';
    p1.name[3] = 't';
    p1.name[4] = 'y';
    p1.name[5] = 'a';
    p1.age = 17;
    p1.salary = 100000;
    p1.gender = male; // enum used

    cout << "Person p1's info:nName: " << p1.name << "nAge: " << p1.age << "nSalary: " <<
    p1.salary << "nGender: " << p1.gender;

    return 0;
}
 

При выполнении кода выше при печати p1.name всегда каждый раз получаю 4 разных случайных персонажа.
Моя версия g : g .exe (i686-posix-dwarf-rev0, Built by MinGW-W64 project) 8.1.0 , с использованием кода Visual Studio(IDE).
Спасибо!

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

1. p1.name не инициализирован, std::string может быть лучшим выбором (и тогда p1.name = "Aditya"; ).

2. Ваш name участник-это указатель … но куда это указывает? Вам нужно будет либо выделить немного памяти и указать на это, либо (возможно, лучше) объявить name в виде массива символов.

3. bool gender; … В то время как вы заявляете enum об этом :/

4. @AdrianMole Из учебников по C я узнал, что мы можем инициализировать массив с помощью этого.

5. @jarod42 Не могли бы вы объяснить, пожалуйста, как использовать std::string

Ответ №1:

Чтобы вы могли узнать о своей ошибке, давайте сначала посмотрим, что не так с вашим кодом.

 typedef struct person
{
    int age;
    char* name;
    float salary;
    bool gender;
} prsn;
 

char * является указателем на какой-то адрес. Поэтому, если вы не используете new его, он укажет на случайный адрес, который ранее был записан в память.

Ваши альтернативы-использовать конструктор и выделить немного памяти:

 struct person () : name (new name(10)) {
}
 

или использовать std::string .

 typedef struct person
{
    int age;
    std::string name;
    float salary;
    bool gender;
} prsn;
 

Еще одно замечание, которое указывает мне на то, чему вы учитесь C не в том месте, — это

 typedef struct person {
} prsn;
 

В C этом делается для того, чтобы избежать инициализации вашей структуры с помощью:

 int main () {
    struct person p1;
    ...
}

 

В C вы можете легко сделать это таким образом:

 int main () {
    person p1;
    ...
}

 

помните struct class , что по умолчанию в поле «С открытыми участниками C «.

 #include <iostream>
using namespace std;

struct person
{
    int age;
    char* name;
    float salary;
    bool gender;

    person () : age (0), char (new char[20]()), salary (0.0), gender (true) {
    }
};

enum Gender
{
    male,
    female
};

int main()
{
    person p1;
    p1.name[0] = 'A';
    p1.name[1] = 'd';
    p1.name[2] = 'i';
    p1.name[3] = 't';
    p1.name[4] = 'y';
    p1.name[5] = 'a';
    p1.age = 17;
    p1.salary = 100000;
    p1.gender = male; // enum used

    cout << "Person p1's info:nName: " << p1.name << "nAge: " << p1.age << "nSalary: " <<
    p1.salary << "nGender: " << p1.gender;

    return 0;
}
 

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

Как и предлагалось, вам следует избегать использования необработанных указателей в C . Вместо std::shared_ptr() этого использует std::unique_ptr() и.

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

1. Спасибо @KPCT. Я должен переключиться на обучение.

2. Вам нужно использовать квадратные скобки после нового. Но в принципе вы вообще не должны использовать необработанные указатели/новые для собственной памяти. . ..

3. @ArminMontigny Я знаю, что вы должны использовать уникальные или фрагментные ptr, но это было основано на вопросе OPs, и я указываю, где он совершает ошибки. Я действительно ценю ваш вклад.