При попытке реализовать итератор двойного указателя я обнаружил кое-что интересное:
- Время вызова деструктора сбивает меня с толку.
- Невозможно понять память адреса объектов.
Объяснение
class A
У меня есть класс с именем A
, который выделит некоторую память для последовательности целых чисел (_ori_aa
).
class A {
public:
// constructor and destructor
// ...
Iter<int> aa() const {
Iter<int> _iter;
_iter.set(_aa, _len);
return _iter;
}
private:
const int _len;
int * _ori_aa; // sequence of numbers: {0, 1, 2, 3}
int ** _aa; // pointers to _ori_aa: {_ori_aa, _ori_aa+1, ...}
};
struct Iter
И структура с именем Iter
, которая может помочь мне перебрать двойной указатель _aa
в объекте A
.
Для наблюдения я печатаю адрес своей памяти (this
) в конструкторе и деструкторе.
Функция meow()
также печатает адрес памяти , но он используется для ручного вызова.
template <typename T>
struct Iter {
Iter() { cout << '+' << this << endl; }
~Iter() { cout << '-' << this << endl; }
// ...
void meow() {
cout << '?' << this << endl;
}
// ...
};
main()
В основной функции
- я создаю объект
A
, а затем вызовите aa()
, который сгенерирует Iter
объект и вернет значение. - Я создаю o наберите
Iter
и наберите meow()
вручную на , см. его адрес . - Я использую на основе диапазона для l oop, чтобы напечатать все числа.
- Я печатаю разделитель, чтобы указать конец l oop.
int main() {
A a;
Iter<int> aa = a.aa(); // copy by value
aa.meow();
for(const int & n : aa) {
cout << n << endl;
}
cout << "-------" << endl;
}
Проблема
Это вывод программы:
+0x7ffee567a9b0
?0x7ffee567a9b0
0
1
2
3
-0x7ffee567a988
-------
-0x7ffee567a9b0
Мои вопросы:
- Каким операциям соответствуют эти печатные адреса?
- Я знаю, что первый адрес печатается, когда
_iter
создается в aa()
, но когда вызывается деструктор? Я думал, что _iter
будет уничтожено сразу после возврата aa()
, хотя это не так. - Я думал, что последний адрес печатается, когда объект
aa
(локальная переменная в main()
) уничтожен. Поскольку он совпадает с адресом _iter
, означает ли это, что память _iter
уже освобождена? Тогда почему деструктор не был вызван? - Какой третий адрес? Почему он отличается от всех адресов, напечатанных конструктором? Почему деструктор вызывается в конце для l oop?
Environment
- ОС: macOS Catalina
- Apple Clang версия 11.0.3 (clang-1103.0.32.29)
- Параметры компиляции:
-std=c++17
Код
Ниже приведен полный код,
#include <iostream>
using namespace std;
template <typename T>
struct Iter {
Iter() { cout << '+' << this << endl; }
~Iter() { cout << '-' << this << endl; }
T ** pp {nullptr};
int len {0};
int it {0};
void meow() {
cout << '?' << this << endl;
}
void set(T ** pi, int l) {
pp = pi;
len = l;
}
Iter & begin() {
it = 0;
return *this;
}
int end() const {
return len;
}
T & operator*() {
return *pp[it];
}
bool operator!=(int rhs) {
return this->it < rhs;
}
Iter & operator++() {
++it;
return *this;
}
};
class A {
public:
A() : _len(4) {
_ori_aa = new int [_len];
_aa = new int * [_len];
for(int i = 0; i < _len; i++) {
_ori_aa[i] = i;
_aa[i] = _ori_aa + i;
}
}
~A() {
delete [] _aa;
delete [] _ori_aa;
}
Iter<int> aa() const {
Iter<int> _iter;
_iter.set(_aa, _len);
return _iter;
}
private:
const int _len;
int * _ori_aa;
int ** _aa;
};
int main() {
A a;
Iter<int> aa = a.aa(); // copy by value
aa.meow();
for(const int & n : aa) {
cout << n << endl;
}
cout << "-------" << endl;
}
Спасибо за чтение!