Не получается обработать exception нарушение доступа для записи
Пишу двусвязный блочный список с индексной таблицей, и он в целом работает, но если попытаться удалить или вставить элементы в конец или начало, часто вылетают исключения (нарушение доступа для записи)
И всё бы ничего, но у меня не получается их обработать, сначала пытался через обычный try catch
, потом через __try __except
, всё равно вылетает исключение. (В классе block с 64 по 75 строку).
Вот собственно и вопрос: как обработать такое исключение?
P.s. Не так долго изучаю программирование в целом, так что если есть советы как лучше или чище писать код буду рад узнать.
#include<iostream>
#include<cmath>
#include<string>
#include <excpt.h>
using namespace std;
string fisrtNames[8] = { "Nolah","Liam","Mason","Jacob","William","Ethan","Michael","Alexander" };
string lastNames[11] = { "Williams","Peters","Gibson","Martin","Jordan","Jackson","Grant","Davis","Collins","Bradlay","Barlow" };
class node {
public:
node() {
size = sizeof(values) / sizeof(*values);
fisrtName = "";
lastName = "";
}
void print() {
cout << "values ---> \t";
for (int i = 0; i < size; i++) {
cout << values[i] << " ";
if (i == size - 1)cout << "\nfirstName -> \t";
}
for (int i = 0; i < fisrtName.length(); i++) {
cout << fisrtName[i];
if (i == fisrtName.length() - 1)cout << "\nlasttName -> \t";
}
for (int i = 0; i < lastName.length(); i++) {
cout << lastName[i];
if (i == lastName.length() - 1)cout << "\n\n";
}
}
int getValuesSize() { return size; }
float* getValuesPtr() { return values; }
void setValueByIndex(int index, float value) { values[index] = value; }
void setFisrtName(string name) { this->fisrtName = name; }
string getFisrtName() { return fisrtName; }
void setLastName(string lastName) { this->lastName = lastName; }
string getLastName() { return lastName; }
private:
float values[7] = { 0 };
string fisrtName;
string lastName;
int size;
};
class block {
public:
block() {
next = nullptr;
previous = nullptr;
countInBlock = 0;
blocksCount++;
number = blocksCount;
}
int getNumber() { return number; }
void setNext(block* next) { this->next = next; }
block* getNext() { return next; }
void setPrevious(block* previous) {
__try {
this->previous = previous; //не обрабатывается исключение
}
__except (EXCEPTION_EXECUTE_HANDLER) {
cout << "Ошибка записи память доступна только для чтения " << endl;
}
}
block* getPrevious() { return previous; }
int getCountInBlock() { return countInBlock; }
int getBlockSize() { return sizeof(mBlock) / sizeof(*mBlock); }
void addInBlock(node& newNode) {
mBlock[countInBlock] = newNode;
countInBlock++;
}
void printBlock() {
cout << "Блок номер " << number << endl;
for (int i = 0; i < countInBlock; i++) { mBlock[i].print(); }
}
private:
node mBlock[2];
block* next, * previous;
int number, countInBlock;
static int blocksCount;
};
int block::blocksCount = 0;
class list {
public:
// Индексная таблица
class indexTable {
public:
void createIndexTable(list& mlist) {
listSize = mlist.getCountBlocksInList();
offset = listSize / 4;
if (offset == 0) offset++;
block* nextPtr = mlist.getBegin();
while (true) {
if (nowPtrPos == 1) {
table[indexInTable] = nextPtr;
indexInTable++;
}
nextPtr = nextPtr->getNext();
nowPtrPos++;
if (nowPtrPos % offset == 0) {
table[indexInTable] = nextPtr;
indexInTable++;
}
if (nextPtr->getNext() == nullptr || indexInTable == 5) break;
}
}
void printTable() {
cout << "/------------PRINT INDEX TABLE-----------\\ \n\n";
for (int i = 0; i < indexInTable; i++) {
cout << table[i]->getNumber() << endl;
table[i]->printBlock();
cout << "|------------------NEXT------------------|\n\n";
}
cout << "\\---------------TABLE END-----------------/ \n\n";
}
int getOffset() { return offset; }
block* getBlockByIndex(int index) { return table[index]; }
private:
block* table[5];
int listSize = 0, nowPtrPos = 1, offset = 0, indexInTable = 0;
};
// НАЧАЛО КОНЕЦ
enum addType {
BEGIN,
END
};
// Получение кол-ва блоков в листе
int getCountBlocksInList() { return countBlocks; }
//Получение указателя на первй блок
block* getBegin() { return begin; }
// Добавление в начало списка
void addToStart(block* newBeginBlock) {
begin->setPrevious(newBeginBlock);
newBeginBlock->setNext(begin);
this->begin = newBeginBlock;
countBlocks++;
}
// Добавление в конец списка
void addToEnd(block* newBlock) {
if (countBlocks == 0) addToStart(newBlock);
else {
block* nextPtr = begin;
while (nextPtr->getNext()) {
nextPtr = nextPtr->getNext();
}
nextPtr->setNext(newBlock);
newBlock->setPrevious(nextPtr);
countBlocks++;
}
}
// Вставка блока
void insert(int index, block* newBlock,indexTable& table) {
block* nextPtr;
int offset = table.getOffset();
if (index < offset) index--;
nextPtr = table.getBlockByIndex((index/offset));
for (int i = 0; i < index % offset; i++) {
nextPtr = nextPtr->getNext();
}
//nextPtr->printBlock();
//nextPtr->getPrevious()->printBlock();
//nextPtr->getNext()->printBlock();
nextPtr->getPrevious()->setNext(newBlock);
newBlock->setPrevious(nextPtr->getPrevious());
newBlock->setNext(nextPtr);
nextPtr->setPrevious(newBlock);
countBlocks++;
}
// Удалени блока
void destroy(int index, indexTable& table) {
block* nextPtr;
int offset = table.getOffset();
if (index < offset) index--;
nextPtr = table.getBlockByIndex((index / offset));
for (int i = 0; i < index % offset; i++) {
nextPtr = nextPtr->getNext();
}
nextPtr->getPrevious()->setNext(nextPtr->getNext());
delete(nextPtr);
countBlocks--;
}
// Очистка всего списка
void clear() {
block* nextPtr = begin, * previous;
while (nextPtr) {
previous = nextPtr;
nextPtr = nextPtr->getNext();
delete(previous);
}
}
// Вывод всего листа
void printList() {
int ptrPos = 1;
block* nextPtr = begin;
cout << "/---------------PRINT LIST START---------------\\ \n\n";
while (ptrPos <= countBlocks) {
nextPtr->printBlock();
cout << "|------------------NEXT BLOCK------------------|\n\n";
nextPtr = nextPtr->getNext();
ptrPos++;
}
cout << "\\---------------PRINT LIST END-----------------/ \n\n";
}
// Вывод конкретного блока
void printBlock(int index) {
}
// Генерация заданного кол-ва node
void genNodes(int count, addType addType) {
int blocksWill, addedBlocks = 0;
block* newBlock = new block;
if (count % newBlock->getBlockSize() == 0) blocksWill = count / newBlock->getBlockSize();
else { blocksWill = (count / newBlock->getBlockSize() + 1); }
for (int i = 0; i < count; i++) {
node newNode;
newNode.setFisrtName(fisrtNames[0 + rand() % 8]);
newNode.setLastName(lastNames[0 + rand() % 11]);
for (int j = 0; j < newNode.getValuesSize(); j++) {
newNode.setValueByIndex(j, rand() % 201 - 100);
}
if (newBlock->getCountInBlock() == newBlock->getBlockSize()) {
if (addType == BEGIN) addToStart(newBlock);
else addToEnd(newBlock);
addedBlocks++;
newBlock = new block;
}
newBlock->addInBlock(newNode);
}
if (addedBlocks < blocksWill) {
if (addType == BEGIN) addToStart(newBlock);
else addToEnd(newBlock);
}
cout << "Сгенерированно " << blocksWill << " блоков" << endl;
}
// Герерация одного блока
block* genBlock() {
block* newBlock = new block;
for (int i = 0; i < newBlock->getBlockSize(); i++) {
node newNode;
newNode.setFisrtName(fisrtNames[0 + rand() % 8]);
newNode.setLastName(lastNames[0 + rand() % 11]);
for (int j = 0; j < newNode.getValuesSize(); j++) {
newNode.setValueByIndex(j, rand() % 201 - 100);
}
newBlock->addInBlock(newNode);
}
return newBlock;
}
private:
block* begin;
int countBlocks = 0;
};
int main() {
setlocale(LC_ALL, "Russian");
list mList;
list::indexTable mTable;
string command;
while (true) {
cout << "//--Список доступных команд--//" <<
"\n1.Генериция заданного кол-ва записей -> \tGENNODES\n2.Создание/Пересоздание индексной таблицы -> \tGENTABLE\n3.Вывод индексной таблицы -> \t\t\tPRINTTABLE" <<
"\n4.Удаление блока -> \t\t\t\tDESTROY\n5.Вывод листа -> \t\t\t\tPRINTLIST\n6.Вывод конкретного блока -> \t\t\tPRINTBLOCK" <<
"\n7.Очистка информационного листа -> \t\tCLEAR\n8.Выход -> \t\t\t\t\tQUIT\n\n";
cin >> command;
if (command == "GENNODES") {
cout << "Введите кол-во ->\n";
int cont;
cin >> cont;
cout << "Куда добавить 1 - начало 2 - конец\n";
int addType;
cin >> addType;
if (addType == 1) { mList.genNodes(cont, list::BEGIN); }
if (addType == 2) { mList.genNodes(cont, list::END); }
continue;
}
if (command == "GENTABLE") {
mTable.createIndexTable(mList);
}
if (command == "PRINTTABLE") {
mTable.printTable();
continue;
}
if (command == "INSERT") {
cout << "Куда вставить индекс(int)\n";
int index;
cin >> index;
mList.insert(index, mList.genBlock(),mTable);
continue;
}
if (command == "DESTROY") {
cout << "Откуда удалить индекс(int)\n";
int index;
cin >> index;
mList.destroy(index,mTable);
continue;
}
if (command == "PRINTLIST") {
mList.printList(); continue;
}
if (command == "PRINTBLOCK") {
cout << "Какой блок вывести индекс(int)\n";
int index;
cin >> index;
mList.printBlock(index);
continue;
}
if (command == "CLEAR") {
mList.clear();
continue;
}
if (command == "QUIT") return 0;
}
return 0;
}