Двойная свобода или коррупция, почему это появляется?

Я почти закончил свой умный указатель (я знаю …), поэтому я загрузил его на сайт моего университета, который запускает ряд автоматических тестов для моего кода. В ряде тестов есть две ошибки:

  • Превышен лимит памяти или времени
  • Проблема с доступом к памяти (т. Е. Нулевой указатель)

Дело в том, что я не знаю, какие тесты выполняются. Я могу прочитать стандартный вывод автоматизированных тестов, который написан там:

In instantiation of ‘my_pointer<T>::my_pointer() [with T = tester]’:
error: no matching function for call to ‘tester::tester()’
note: candidates are:
tester::tester(my_pointer<tester>)
candidate expects 1 argument, 0 provided
tester::tester(const tester&)
candidate expects 1 argument, 0 provided

Так что я предполагаю, что по какой-то странной причине он не вызовет мой конструктор my_pointer ()?
Это мой умный указатель класса:

template<class T>
class my_pointer {
T* raw_pointer;

public:
my_pointer() {
raw_pointer = new T();
raw_pointer->incRefCnt();
}

my_pointer(T *obj) : raw_pointer(obj) {
if(raw_pointer != NULL) raw_pointer->incRefCnt();
}

my_pointer(const my_pointer<T>& smart_pointer) : raw_pointer(smart_pointer.raw_pointer) {
if(raw_pointer != NULL) raw_pointer->incRefCnt();
}

T& operator*() {
return *raw_pointer;
}

T* operator->() {
return raw_pointer;
}

operator T*() {
return raw_pointer;
}

my_pointer<T> &operator=(const my_pointer<T> &smart_pointer) {
if(this != &smart_pointer && raw_pointer != NULL) {
/** if this was the last reference to the given memory address */
if (raw_pointer->decRefCnt() == 0) {
delete raw_pointer;
}

raw_pointer = smart_pointer.raw_pointer;
raw_pointer->incRefCnt();
}

return *this;
}

bool operator== (const T* pointer) {
return raw_pointer == pointer;
}

bool operator!= (const T* pointer) {
return raw_pointer != pointer;
}

bool operator== (const my_pointer<T> &smart_pointer) {
return raw_pointer == smart_pointer.raw_pointer;
}

bool operator!= (const my_pointer<T> &smart_pointer) {
return raw_pointer != smart_pointer.raw_pointer;
}

~my_pointer() {
if(raw_pointer->decRefCnt() == 0 && raw_pointer != NULL) {
delete raw_pointer;
}
}
};

Это класс, в котором ссылки могут быть подсчитаны:

class refcounted {
private:
int count;
public:
refcounted() : count(0) { }

int incRefCnt() {
return ++count;
}

int decRefCnt() {
return --count;
}
};

Вы видите какие-либо проблемы с кодом? Заранее спасибо!

-2

Решение

Вы безоговорочно удаляете свой необработанный указатель в деструкторе. Это не верно. Вы должны уменьшить счетчик ссылок и удалять только если он становится равным нулю.

Вы также звоните raw_pointer->incRefCnt(); в нескольких местах без проверки raw_pointer является NULL,

3

Другие решения

Я вижу две проблемы в вашем коде:

  1. В операторе = (): вы проверяете if(raw_pointer != NULL) после того, как вы уже разыменовались raw_pointer (на строке выше). Вы должны отменить чеки.

  2. В деструкторе: ты не должен сначала позвонить decRefCnt()и только удалить raw_pointer если счетчик ссылок упал до нуля?

Поскольку вам нужно практически одинаковый код в обоих operator=() а также ~my_pointer() для уменьшения количества ссылок и удаления raw_pointer, если необходимо (AFAICS), представляется более практичным извлечь эту функциональность в новый метод и вызывать ее из обоих мест.

0

По вопросам рекламы [email protected]