А что тебе мешает написать конструктор копии, в котором ты будешь нормально создавать копию?
Так я же и написал его:
Test(Test &right)
{
abc= new PRICE;
strcpy(abc->name,right.abc->name);
strcpy(abc->shop,right.abc->shop);
abc->cost=right.abc->cost;
}
Можно. Структура скопируется полностью как надо, т.к. память здесь не выделяемая, а фиксированная.
Нет, ну я же переделал по твоему совету чтобы был указатель abc (ну чтобы деструктору было чем заняться
) так что память теперь выделяемая.
Хотя там программа то уже как видишь работает и в ней всё ок, а вот теперь мне надо переделать ту где динамическая структура (та которая двунаправленный список), вот в ней то и начинается всё интересное.
Просто эта динам. структура (я ещё тогда переделал твой вариант вытянув все функции из структуры в класс и поправив указатели, в структуре лишь оставил конструктор по умолчанию) ведёт себя слегка странно.
Вариант 1
всё работает хорошо:
#include <iostream>
#include <cstring>
using namespace std;
class Test
{
public:
struct ListItem;
// Конструктор по умолчанию
Test(string data)
{
abc=new ListItem(data);
}
// Печать списка
void print_list()
{
ListItem* item = this->abc;
while(item)
{
cout << item->data;
item = item->next;
if(item) cout << " ";
}
cout << endl;
}
// Удаляет первые символы в строках
void assigned()
{
ListItem* item=this->abc;
while (item)
{
item->data.assign(&item->data[1]);
item=item->next;
}
}
//Добавляет инвертированный список
void plus_invert ()
{
ListItem *item=this->getTail();
while (item)
{
this->addToTail(item->data);
item = item->prev;
}
}
ListItem* getTail()
{
ListItem* item = abc;
while(item->next)
item = item->next;
return item;
}
ListItem* addToTail(const string data)
{
ListItem *item = new ListItem(data), *last = getTail();
item->prev = last;
last->next = item;
return item;
}
ListItem* findLastItem(const string data)
{
ListItem* item = abc, *last = NULL;
while(item->next)
{
if(item->data == data)
{
last = item;
}
item = item->next;
}
return last;
}
bool insertAfterLastItem(const string data, Test list)
{
ListItem* last = findLastItem(data), *next_item, *prev_item, *list_last;
if(!last) return false;
next_item = last->next;
list_last = getTail();
list_last->next = next_item;
if(next_item)
next_item->prev = list_last;
list.abc->prev = last;
last->next = list.abc;
return true;
}
struct ListItem
{
string data; // Хранимые в элементе списка данные
ListItem *prev, *next; // Указатели на предыдущий и следующий элементы
// Конструктор
ListItem(const string data):prev(NULL),next(NULL)
{
this->data = data;
}
~ListItem()
{
if(next) delete next;
}
};
ListItem *abc;
};
int main()
{
Test a("aa1");
a.addToTail("aa2");
a.addToTail("aa3");
a.addToTail("aa4");
cout << "List a: ";
a.print_list();
Test b("bb1");
b.addToTail("bb2");
b.addToTail("bb3");
b.addToTail("bb4");
cout << "List b: ";
b.print_list();
a.insertAfterLastItem("aa3", b);
cout << "Merged: ";
a.print_list();
a.assigned();
cout<<"After deleting first symbol: ";
a.print_list();
a.plus_invert();
cout<<"After inverting (and append): ";
a.print_list();
return 0;
}
И тут я добавляю деструктор что удаляет мой указатель abc на структру ...
#include <iostream>
#include <cstring>
using namespace std;
class Test
{
public:
struct ListItem;
// Конструктор по умолчанию
Test(string data)
{
abc=new ListItem(data);
}
~Test()
{
cout<<"Destructor runs";
delete abc;
}
// Печать списка
void print_list()
{
ListItem* item = this->abc;
while(item)
{
cout << item->data;
item = item->next;
if(item) cout << " ";
}
cout << endl;
}
// Удаляет первые символы в строках
void assigned()
{
ListItem* item=this->abc;
while (item)
{
item->data.assign(&item->data[1]);
item=item->next;
}
}
//Добавляет инвертированный список
void plus_invert ()
{
ListItem *item=this->getTail();
while (item)
{
this->addToTail(item->data);
item = item->prev;
}
}
ListItem* getTail()
{
ListItem* item = abc;
while(item->next)
item = item->next;
return item;
}
ListItem* addToTail(const string data)
{
ListItem *item = new ListItem(data), *last = getTail();
item->prev = last;
last->next = item;
return item;
}
ListItem* findLastItem(const string data)
{
ListItem* item = abc, *last = NULL;
while(item->next)
{
if(item->data == data)
{
last = item;
}
item = item->next;
}
return last;
}
bool insertAfterLastItem(const string data, Test list)
{
ListItem* last = findLastItem(data), *next_item, *prev_item, *list_last;
if(!last) return false;
next_item = last->next;
list_last = getTail();
list_last->next = next_item;
if(next_item)
next_item->prev = list_last;
list.abc->prev = last;
last->next = list.abc;
return true;
}
struct ListItem
{
string data; // Хранимые в элементе списка данные
ListItem *prev, *next; // Указатели на предыдущий и следующий элементы
// Конструктор
ListItem(const string data):prev(NULL),next(NULL)
{
this->data = data;
}
~ListItem()
{
if(next) delete next;
}
};
ListItem *abc;
};
int main()
{
Test a("aa1");
a.addToTail("aa2");
a.addToTail("aa3");
a.addToTail("aa4");
cout << "List a: ";
a.print_list();
Test b("bb1");
b.addToTail("bb2");
b.addToTail("bb3");
b.addToTail("bb4");
cout << "List b: ";
b.print_list();
a.insertAfterLastItem("aa3", b);
cout << "Merged: ";
a.print_list();
a.assigned();
cout<<"After deleting first symbol: ";
a.print_list();
a.plus_invert();
cout<<"After inverting (and append): ";
a.print_list();
return 0;
}
И получаю очень интересную картину...
Если честно то у меня разрыв шаблона: я всегда думал что программа при попытке обратиться к памяти где данные другой программы то получит отказ, а оно во как.
Добавлено позже:Ну как я понимаю у меня что-то не так с insertAfterLastItem (после её работы здесь такое начинается), но почему без написания моего деструктора проблем нет мне непонятно. И в итоге непонятно с insertAfterLastItem что-то не так или с деструктором что-то не так.
Добавлено позже:Такс, нашёл одну из ошибок (я балда амперсант не поставил и там передавалась копия этой insertAfterLastItem вместо оригинала), но теперь программа не доходит до конца и после запуска деструктора зависает, притом зависает не всегда, а в процентах 70%
Пытается освободить уже освобождённую память где-то чтоль? Так почему не каждый раз тогда зависает ...
#include <iostream>
#include <cstring>
using namespace std;
class Test
{
public:
struct ListItem;
// Конструктор по умолчанию
Test(string data)
{
abc=new ListItem(data);
}
~Test()
{
cout<<"DESTRUCTOR RUNS\n";
delete abc;
}
// Печать списка
void print_list()
{
ListItem* item = this->abc;
while(item)
{
cout << item->data;
item = item->next;
if(item) cout << " ";
}
cout << endl;
}
// Удаляет первые символы в строках
void assigned()
{
ListItem* item=this->abc;
while (item)
{
item->data.assign(&item->data[1]);
item=item->next;
}
}
//Добавляет инвертированный список
void plus_invert ()
{
ListItem *item=this->getTail();
while (item)
{
this->addToTail(item->data);
item = item->prev;
}
}
ListItem* getTail()
{
ListItem* item = abc;
while(item->next)
item = item->next;
return item;
}
ListItem* addToTail(const string data)
{
ListItem *item = new ListItem(data), *last = getTail();
item->prev = last;
last->next = item;
return item;
}
ListItem* findLastItem(const string data)
{
ListItem* item = abc, *last = NULL;
while(item->next)
{
if(item->data == data)
{
last = item;
}
item = item->next;
}
return last;
}
bool insertAfterLastItem(const string data, Test &list)
{
ListItem* last = findLastItem(data), *next_item, *prev_item, *list_last;
if(!last) return false;
next_item = last->next;
list_last = getTail();
list_last->next = next_item;
if(next_item)
next_item->prev = list_last;
list.abc->prev = last;
last->next = list.abc;
return true;
}
struct ListItem
{
string data; // Хранимые в элементе списка данные
ListItem *prev, *next; // Указатели на предыдущий и следующий элементы
// Конструктор
ListItem(const string data):prev(NULL),next(NULL)
{
this->data = data;
}
~ListItem()
{
if(next) delete next;
}
};
ListItem *abc;
};
int main()
{
Test a("aa1");
a.addToTail("aa2");
a.addToTail("aa3");
a.addToTail("aa4");
cout << "List a: ";
a.print_list();
Test b("bb1");
b.addToTail("bb2");
b.addToTail("bb3");
b.addToTail("bb4");
cout << "List b: ";
b.print_list();
a.insertAfterLastItem("aa3", b);
cout << "Merged: ";
a.print_list();
a.assigned();
cout<<"After deleting first symbol: ";
a.print_list();
a.plus_invert();
cout<<"After inverting (and append): ";
a.print_list();
return 0;
}
Добавлено позже:Да что же это такое, я же деструктор то оставил в самой структуре и ему заняться нечем кроме как освобождения повторно памяти, во туплю сегодня.