Двойные бесплатные ошибки при использовании мелких копий объектов ... как исправить? - PullRequest
3 голосов
/ 11 марта 2011

Как удалить двойные (удалить) ошибки из мелко скопированного объекта по сравнению с исходным объектом.

Простой пример:

class INT
{
   int *p; //dynamic.

   //define here fancy constructors etc.
   set(int i){ p=new int; p=i;}
   ~INT();
}

INT::~INT()
{
   if(p) delete p;
}

void somefunction(INT a)
{
   //done some stuff ,e.g. call some display function
}
//note here, that a destructor will be called, and a.p will vanish.

int main(void)
{
   INT a; a.set(2);
   somefunction(a);//shallow copy
}
//CRASH BOOM BOOM!

Я хотел бы универсальное решение, потому что передача объектовтривиальная вещь, и такая же наивная, как эта, приводящая к ужасной / ужасной ошибке, просто «потрясающая».

Я подозреваю, что есть много способов обойти это (некоторые из которых даже я могу придумать), ноМне было любопытно, есть ли какой-нибудь общий (применимый почти везде) способ решения этой проблемы?

Ответы [ 4 ]

5 голосов
/ 11 марта 2011

Всякий раз, когда у вас есть объект apointer внутри вашего класса, вам нужно объявить свой собственный конструктор копирования и метод оператора присваивания, чтобы избежать проблемы поверхностного копирования.Посмотрите эту ссылку для получения более подробной информации об этом

3 голосов
/ 11 марта 2011

Пациент: Доктор, мне больно, когда я делаю это!
Доктор: Не делай этого.

Скорее всего, по крайней мере, 100: 1 вы сможете написать свой код без проблем с необработанным указателем. В зависимости от ситуации вам может понадобиться умный указатель или вам может потребоваться коллекция, но шансы на то, что вам нужен указатель, кажутся весьма отдаленными.

Вместо того, чтобы спрашивать о том, как исправить то, что вы делаете, вам гораздо лучше рассказать нам о том, чего вы пытаетесь достичь, и мы можем рассказать вам, как это сделать.

2 голосов
/ 11 марта 2011

Для всех объектов с динамическими элементами обычно лучше всего определять свои собственные операции копирования и назначения копирования именно по этой причине.

Относительно «больших» объектов и дорогостоящего копирования, подсчет ссылок - это метод, используемый многими языками и шаблонами для обхода этой проблемы владения указателем.Обратите внимание, что в этом случае все копии объекта указывают на один и тот же общий объект, поэтому модификация общего объекта из одного экземпляра будет видна другим.См. boost shared_ptr документацию для получения дополнительной информации.

1 голос
/ 11 марта 2011

Вопрос "Как избежать двойного удаления из мелких копируемых объектов?" действительно должно быть «Как избежать мелких копий, когда я этого не хочу?».

Некоторые опции:
- избегайте необработанных указателей на выделенную память
- не копируйте объекты! : -)
- управлять памятью вне объектов
- используйте умный указатель
- реализовать глубокое копирование

Ваш выбор зависит от того, для чего вы на самом деле используете свои объекты.

...