Тема: C++ Класи. Допоможіть знайти де я виходжу за межі масиву
Друзі, допоможіть. Створив клас Поштова скринька в яку я додаю повідомлення, виводжу їх на екран і видаляю.
Помітив наступну помилку: якщо додати 3 повідомлення (S1R1M1, S2R2M2, S3R3M3), потім видалити третє (2 по індексу), знову його додати, потім видалити перше (0 по індексу) і спробувати вивести повідомлення з індексом 1, то програма завершується з помилкою. Я так розумію, що щось десь виходить за межі масиву, але не розумію де.
Допоможіть розібратися. Усі маніпуляції проводив з Завданням 2! Ось код:
/*Розробіть клас Message, який моделює повідомлення електронної пошти.
Повідомлення містить одержувача, відправника, текст повідомлення, час створення.
Необхідні наступні функції-члени:
• конструктор, який приймає відправника і одержувача і встановлює часову відмітку (time stamp)
• Функція-член append, яка додає рядок тексту в тіло повідомлення
• Функція-член to_string, яка перетворює повідомлення в один довгий рядок, напр.: "From:
Harry Hacker\nTo: Rudolf Reindeer\n ..."
• Функція-член print, яка друкує текст повідомлення. Порада: Використовуйте to_string.
Для створення time stamp використайте функції і типи, визначені у ctime.h
Другий етап
Розробіть клас MessageBox, котрий моделює поштову скриньку.
Він повинен зберігати повідомлення у масиві (визначтеся, це має бути масив об'єктів, чи масив вказівників на об'єкти)
Реалізуйте наступні функції-члени:
Додавання нового повідомлення (void MessageBox::add_message(Message m);)
Повернути повідомлення по індексу (Message MessageBox::get_message(int i) const;)
Видалити повідомлення по індексу (void MessageBox::remove_message(int i);)
*/
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<ctime>
#include <string>
using namespace std;
#pragma region Task_1
class Message
{
string sender;
string receiver;
time_t curr_time;
string message_body;
public:
Message()
{
}
Message(const Message &obj)
{
sender = obj.sender;
receiver = obj.receiver;
curr_time = obj.curr_time;
message_body = obj.message_body;
}
void add_message()
{
cout << "Enter e-mail of a sender : ";
cin.ignore();
getline(cin, sender);
cout << "Enter e-mail of a receiver : ";
getline(cin, receiver);
append();
curr_time = time(0);
}
//Функція-член append, яка додає рядок тексту в тіло повідомлення
void append()
{
cout << "Type your message : " << endl;
getline(cin, message_body);
}
//Функція-член to_string, яка перетворює повідомлення в один довгий рядок, напр.: "From: Harry Hacker\nTo: Rudolf Reindeer\n ..."
string to_string()
{
string full = "From: " + sender + "\nTo: " + receiver + "\nMessage: " + message_body + "\nTime: " + ctime(&curr_time);
return full;
}
//Функція-член print, яка друкує текст повідомлення. Порада: Використовуйте to_string
void print()
{
cout << to_string();
}
};
void task1()
{
Message *My = new Message();
My->add_message();
My->print();
system("pause");
}
#pragma endregion
#pragma region Task_2
/*Другий етап
Розробіть клас MessageBox, котрий моделює поштову скриньку.
Він повинен зберігати повідомлення у масиві (визначтеся, це має бути масив об'єктів, чи масив вказівників на об'єкти)
Реалізуйте наступні функції-члени:
Додавання нового повідомлення (void MessageBox::add_message(Message m);)
Повернути повідомлення по індексу (Message MessageBox::get_message(int i) const;)
Видалити повідомлення по індексу (void MessageBox::remove_message(int i);)*/
class MessageBox
{
private:
int size;
Message *All;
public:
MessageBox(int size)
{
size = 0;
All = new Message[size];
}
//Додавання нового повідомлення (void MessageBox::add_message(Message m);)
#pragma region Add_Message
private:
//void get_message_from_user(Message &single)
//{
// single.add_message();
//}
void move_class(Message *dst)
{
for (Message *src_ptr = All, *dst_ptr = dst; src_ptr < All + size; ++dst_ptr, ++src_ptr)
{
*dst_ptr = *src_ptr;
}
}
Message* AddClass()
{
int newSize = size + 1;
Message *new_box = new Message[newSize];
move_class(new_box);
(new_box + newSize - 1)->add_message();
//get_message_from_user(*(new_box + newSize - 1));
size = newSize;
delete[] All;
All = NULL;
return new_box;
}
public:
void add_message()
{
char YesOrNot;
do
{
All = AddClass();
cout << "Object added" << endl;
do
{
cout << "Add another object? (y/n): ";
cin >> YesOrNot;
} while (YesOrNot != 'y' && YesOrNot != 'n');
} while (YesOrNot != 'n');
}
#pragma endregion
//Повернути повідомлення по індексу (Message MessageBox::get_message(int i) const;)
#pragma region Show_message
private:
bool check_index(const int index)
{
bool is_in = false;
if (index >= 0 && index < size)
{
is_in = true;
}
return is_in;
}
public:
void show_message()
{
int index;
char YesOrNo;
do
{
cout << "Enter the index of a message to show : ";
cin >> index;
if (check_index(index))
{
(All + index)->print();
}
else
{
cout << endl << "***** Invalid index! *****" << endl << endl;
}
do
{
cout << "Show another message? (y/n): ";
cin >> YesOrNo;
} while (YesOrNo != 'y' && YesOrNo != 'n');
} while (YesOrNo != 'n');
}
#pragma endregion
//Видалити повідомлення по індексу (void MessageBox::remove_message(int i);)
#pragma region Delete_message
private:
Message *delete_1_message(const int index)
{
int new_size = size - 1;
Message *new_All = new Message[new_size];
for (Message *ptr = All, *dst = new_All; ptr < All + (size - 1); ++dst, ++ptr)
{
if (ptr == All + index)
{
++ptr;
}
*dst = *ptr;
}
size = new_size;
if (All != nullptr)
{
delete[] All;
All = NULL;
}
return new_All;
}
public:
void delete_messages()
{
int index;
char YesOrNo;
do
{
cout << "Enter the index of a message to delete : ";
cin >> index;
if (check_index(index))
{
All = delete_1_message(index);
cout << endl << "***** Message deleted *****" << endl << endl;
}
else
{
cout << endl << "***** Invalid index! *****" << endl << endl;
}
do
{
cout << "Delete another message? (y/n): ";
cin >> YesOrNo;
} while (YesOrNo != 'y' && YesOrNo != 'n');
} while (YesOrNo != 'n');
}
#pragma endregion
};
void task2()
{
int size = 0;
MessageBox box = MessageBox(size);
enum Menu
{
exit, add, show, remove
};
int choice = 0;
do
{
do
{
cout << "Choose action :" << endl
<< Menu::add << ". Add message to the box" << endl
<< Menu::show << ". Show message by index" << endl
<< Menu::remove << ". Delete message by index" << endl
<< Menu::exit << ". Exit" << endl << endl
<< "Make a choice : ";
cin >> choice;
} while (choice < Menu::exit && choice > Menu::remove);
switch (choice)
{
case Menu::add: box.add_message();
break;
case Menu::show: box.show_message();
break;
case Menu::remove: box.delete_messages();
break;
case Menu::exit: cout << "Good bye!" << endl;
default:
break;
}
} while (choice != Menu::exit);
}
#pragma endregion
void main()
{
enum Menu
{
exit, t1, t2
};
int choice = 0;
do
{
do
{
cout << "Choose action :" << endl
<< Menu::t1 << ". Task 1. Message" << endl
<< Menu::t2 << ". Task 2. Message box" << endl
<< Menu::exit << ". Exit" << endl << endl
<< "Make a choice : ";
cin >> choice;
} while (choice < Menu::exit && choice > Menu::t2);
switch (choice)
{
case Menu::t1: task1();
break;
case Menu::t2: task2();
break;
case Menu::exit: cout << "Good bye!" << endl;
break;
default:
break;
}
} while (choice != Menu::exit);
system("pause");
}