Важная информация
Показано с 1 по 2 из 2

Тема: Программа на С++ неожиданно завершает работу (выделение памяти)

  1. #1 Программа на С++ неожиданно завершает работу (выделение памяти) 
    Новичок
    Регистрация
    29.11.2017
    Сообщений
    7
    Сказал(а) спасибо
    8
    Поблагодарили 1 раз в 1 сообщении
    Заголовочный файл:
    C++ Code:
    1.  
    2. #include <stdlib.h>
    3. #include <string.h>
    4. #include <iostream>
    5.  
    6. using namespace std;
    7.  
    8. class Tel
    9. {
    10. public:
    11. Tel(int, const char *, float);
    12.    void Print(void);
    13.    void Input(void);
    14.    void Downcost(void);
    15. private:
    16. int Number;
    17. char Mark [20];
    18. float Summ;
    19. };
    20.  
    21. Tel::Tel(int Number, const char *Mark, float Summ)
    22. {
    23.   Tel::Number=Number;
    24.   strcpy(Tel::Mark, Mark);
    25.   Tel::Summ=Summ;
    26. }
    27.  
    28. void Tel::Print(void)
    29. {
    30.   cout<<Number<<" "<<Mark<<" "<<Summ<<" "<<endl;
    31. }
    32.  
    33. void Tel::Input()
    34. {
    35.   cin>>Number>>Mark>>Summ;
    36. }
    37.  
    38. void Tel:: Downcost(void)
    39. {
    40.   cout<<"Discount prices: "<<Summ-5000<<endl<<endl;
    41. }


    Главная функция:
    C++ Code:
    1. int main()
    2. {
    3. Tel mobile(1, "Nokia N97", 19999.9);
    4. mobile.Print();
    5. mobile.Downcost();
    6. Tel *mob2;
    7. mob2 = new Tel(2, "Samsung J3", 23599.9);
    8. mob2->Print();
    9. mob2->Downcost();
    10. delete mob2;
    11. Tel *mob3;
    12. mob3->Input();
    13. mob3->Print();
    14. system("pause");
    15.     return 0;
    16. }


    Всё нормально компилируется и запускается, но, после введения третьего элемента, появляется стандартное предупреждение Windows о том, что работа программы прекращена, и система завершает работу программы, возвращая какое-то "левое" значение. Я не могу понять, что именно не так. А Вы?
    Последний раз редактировалось rrrFer; 15.08.2018 в 08:04.
    Ответить с цитированием  
     

  2. #2  
    Профи Аватар для rrrFer
    Регистрация
    01.08.2013
    Сообщений
    561
    Сказал(а) спасибо
    34
    Поблагодарили 248 раз(а) в 164 сообщениях
    Тут ты создал объект на стеке:
    C++ Code:
    1. Tel mobile(1, "Nokia N97", 19999.9);

    память выделилась при входе в функцию, объект будет удален при выходе из нее.

    Тут ты создал объект в куче:
    C++ Code:
    1. mob2 = new Tel(2, "Samsung J3", 23599.9);

    выделил память вручную (c new), удаляет корректно с delete.

    Ну а тут ты создал указатель и не выделил память. Указатель "указывает" на область памяти, которая не распределена, т.е. в ней может находиться что-то полезное. И вот ты залазишь в эту область и и пытаешься вызвать использовать ее как объект класса Tel. Программа могла бы и не упасть - ее поведение с этого момента зависит от фазы луны.

    Что касается кода вцелом (если интересно) - то:
    1. вместо void Print(void); лучше писать void Print();
    потому что общее правило - не писать лишнего.

    2. Тут не нужно писать return 0:
    C++ Code:
    1. int main()
    2. {
    3. // ...
    4.     return 0;

    потому что функция main по умолчанию (и это гарантируется стандартом уже давно) возвращает 0. Ну опять ты пишешь лишнее, т.е. код, который и так компилятор сгенерирует.

    3. Тут не нужно указывать область видимости Tel::
    C++ Code:
    1. Tel::Number=Number;
    2.   strcpy(Tel::Mark, Mark);
    3.   Tel::Summ=Summ;

    Новичок запутается, а опытный программист напряжется, т.к. в некоторых случаях ::Mark или Tel::Mark и Mark может означать разные вещи. Ну если в базовом классе и классах наследниках есть поля с одинаковыми именами - то достучаться до них можно вот так - указывая явно область видимости. Я бы параметрам функции дал другие имена - можно с символом подчеркивания:

    C++ Code:
    1. Tel::Tel(int Number_, const char *Mark_ float Summ_)
    2. {
    3.   Number=Number_;
    4.   strcpy(Mark, Mark_);
    5.   Summ=Summ_;
    6. }


    4. Правилом хорошего тона считается выделение с помощью заглавных букв переменных (полей) и имен классов.
    Ну т.е. я бы вместо полей Number, Mark - писал number и mark и тогда сразу было бы понятно что это переменная, а не имя класса. А вот Tel так и оставил бы с заглавной буквой.

    5. Вот тут у тебя поехало форматирование:
    C++ Code:
    1.    void Downcost(void);
    2. private:
    3. int Number;
    4.  
    5. //...
    6. mob2->Downcost();
    7. delete mob2;
    8. Tel *mob3;
    9. mob3->Input();
    10. mob3->Print();
    11. system("pause");
    12.     return 0;


    Это ухудшает читаемость кода.
    Больше про правильное оформление кода можно почитать в книгах Боба Мартина, например или в статьях типа этой: "[Ссылки могут видеть только зарегистрированные пользователи. ]". Самое главное, что все эти правила придумываются не с потолка, а обосновываются.
    [Ссылки могут видеть только зарегистрированные пользователи. ] // программирование на Prolog, Erlang, C++
    Ответить с цитированием  
     

  3. 3 пользователя(ей) сказали cпасибо:

    >Quiet Snow< (15.08.2018), Free Admin (15.08.2018), Serpent (15.08.2018)

Информация о теме
Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Похожие темы

  1. Игра для Android на развитие памяти
    от rrrFer в разделе Проекты на C/C++
    Ответов: 1
    Последнее сообщение: 16.05.2018, 19:16
  2. подскажите насчет оперативной памяти
    от Вова Филякин в разделе Общие вопросы про железо
    Ответов: 3
    Последнее сообщение: 03.10.2017, 18:35
  3. Выделение всех сообщений в диалоговом окне контакта.
    от Vladislav в разделе Общие вопросы программирования
    Ответов: 1
    Последнее сообщение: 15.01.2013, 16:36
  4. Загрузка DLL из памяти
    от stabud в разделе FreeBasic
    Ответов: 1
    Последнее сообщение: 05.01.2013, 12:57
  5. Получение памяти в DOS из COM программы.
    от Абадябер в разделе Assembler
    Ответов: 11
    Последнее сообщение: 28.11.2011, 21:51
Ваши права
  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •