clarray.h
#ifndef CLARRAY_H
#define CLARRAY_H
#include <iostream>
#include <QString>
using std::cout;
using std::cin;
using std::endl;
class array
{
private:
int* ptr;
int size;
QString name = "tmp_obj";
public:
array(int s, QString name){
size = s;
ptr = new int[s];
this->name = name;
}
array(int s, int* p){
size = s;
ptr = p;
}
~array(){
cout << "destructor " << name.toStdString() << endl;
delete[] ptr;
}
int& operator[](const int& j){
return *(ptr+j);
}
array operator=(const array& cl){
if(this!= &cl){
size = cl.size;
delete[] ptr;
ptr = new int[size];
*ptr = *cl.ptr; // для отладки пусть size == 1
}
cout << "= " << *this->ptr << endl;
return *this;
}
};
#endif // CLARRAY_H
main.cpp
#include <QCoreApplication>
#include <iostream>
#include <clarray.h>
using std::cout;
using std::cin;
using std::endl;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
const int ASIZE = 1;
array *cl = new array(ASIZE, "c1");
array *c2 = new array(ASIZE, "c2");
for(int i = 0; i < ASIZE; i++)
(*cl)[i] = i*i;
*c2 = *cl;
//сразу после присваивания срабатывает деструктор c2
for(int i = 0; i < ASIZE; i++)
cout << "c1: " << (*cl)[i] << " ";
cout << endl;
for(int i = 0; i < ASIZE; i++)
cout << "c2: " << (*c2)[0] << " ";
cout << endl;
delete cl;
delete c2;
// return a.exec();
}
Output
= 0
destructor c2
c1: 0
c2: -572662307
destructor c1
destructor c2
Ещё кидает исключение _crtisvalidheappointer(block), как я понимаю из-за того что я обращаюсь к освобожденному участку памяти.
Вопрос: почему сразу после присваивания срабатывает деструктор?
Оператор присваивания данного класса возвращает временный объект, который и удаляется после вызова этого оператора присваивания.
array operator=(const array& cl){
^^^^^^
if(this!= &cl){
size = cl.size;
delete[] ptr;
ptr = new int[size];
*ptr = *cl.ptr; // для отладки пусть size == 1
}
cout << "= " << *this->ptr << endl;
return *this;
}
Кроме того в результате данного предложения
*ptr = *cl.ptr; // для отладки пусть size == 1
имеется утечка памяти.
Также ваш класс определен таким образом, что трудно определить, сколько элементов динамически распределенного массива было инициализировано, а сколько нет. В общем случае в данном операторе присваивания вы должны копировать актуальные элементы массива, находящегося в правой части от знака присваивания в целевой массив.
Что касается вызова деструктора, то вам следует объявить оператор присваивания следующим образом, то есть возвращать ссылку на объект
array & operator=(const array& cl);
^^^
Данный конструктор
array(int s, int* p){
size = s;
ptr = p;
}
также неверный, так как объект класса должен динамически выделять память для своего массива. Иначе возникает коллизия: кто является владельцем указателя, и кто ответственен за удаления массива, адресуемого указателем?
К тому же вам следует также определить конструктор копирования.
Что касается конструкторов, то вы могли бы определить их следующим образом
#include <algorithm>
//...
array(int s, QString name) : size( s ), name( name )
{
ptr = new int[s];
std::fill( ptr, ptr + size, 0 );
}
array(int s, int* p) : size( s )
{
ptr = new int[s];
std::copy( p, p + s, ptr );
}
Ну смотрите сами: что возвращает ваш оператор?
array operator=(const array& cl){
...
return *this;
}
Именно! array
, а не ссылку на него. Так что return *this;
вызывает конструктор копирования, и возвращает копию - объект array
... который тут же уничтожается - он вам оказался не нужен.
Ну, а раз конструктора копирования у вас нет, то вызывается конструктор копирования по умолчанию - который копирует указатель (т.н. поверхностное копирование). Деструктор его удаляет, и ваш с1
остается с указателем на удаленную память...
Вот и всё.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
У меня есть таблицаКласс Table, унаследованый от QTableWidget и есть база данных
Здравствуйте, возникла проблема при подключении полосы прокрутки к окнуВ общем в окне рисуется график, при этом координаты смещаются с помощью...
При компиляции под win64 все работает корректноПри компиляции под Android вылетает ошибка:
Доброго времени сутокКак мне удалить MySQL полностью? При запуске Installer'a появляется такое окно: