-
Notifications
You must be signed in to change notification settings - Fork 12
Сомов Ярослав #9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
@maksimus-sergeyev, @KirillovAndrey, @VarvaraSharutina можете проверять |
include/stack.h
Outdated
| else throw std::runtime_error("Trying to pop from empty stack"); | ||
| } | ||
|
|
||
| void clear() { while (!isEmpty()) pop(); } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
зачем тут целый цикл? просто sz = 0 не проще?
в зависимости от смысла функции, можно при случае не только sz = 0, но и память освободить частично либо полностью
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
согласен
| TStack& operator=(TStack&& s) noexcept | ||
| { | ||
| TStack tmp(s); | ||
| swap(*this, s); | ||
| return *this; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
утечка памяти. должно быть что-то вроде
TStack& operator=(TStack&& s) noexcept
{
if (this == &s) return *this;
delete[] data;
data = s.data;
sz = s.sz;
cap = s.cap;
s.cap = s.sz = 0;
s.data = nullptr;
return *this;
}
upd: здесь, кстати, тоже не правда, получается. утечки нет, естественно. при условии, что компилятор догадается вызвать перемещающий конструктор, а по идее он должен догадаться, здесь всё приемлемо было.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ок
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
здесь, кстати, тоже не правда, получается. утечки нет, естественно. при условии, что компилятор догадается вызвать перемещающий конструктор, а по идее он должен догадаться, здесь всё приемлемо было.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
держу в курсе, я ещё забыл проверку на самоприсваивание
| ~TStack() | ||
| { | ||
| sz = 0; | ||
| cap = 0; | ||
| delete[] data; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
желательно ещё data = nullptr;
поскольку, например, деструктор можно вызвать принудительно, то бишь вручную,
например так
PtrClass * ptr = new PtrClass();
ptr->~PtrClass();
то при повторном вызове деструктора, не положив data := nullptr,
на строке
delede[] data;
вылетит ошибка о попытке повторного освобождения памяти (upd: в зависимости от стандарта и компилятора может даже и не ошибка, а неопределенное поведение будет).
А, если всё-таки data = nullptr, то delete от nullptr'а, согласно стандарту, должен отработать корректно, то есть никак:
"The value of the first argument supplied to a deallocation function may be a null pointer value; if so, and if the deallocation function is one supplied in the standard library, the call has no effect."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
согласен
| TStack(const TStack& s) : sz(s.sz), cap(s.cap) | ||
| { | ||
| data = new T[cap]; | ||
| std::copy(s.data, s.data + cap, data); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
можно копировать не весь стек вплоть до cap, а только до sz
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
согласен
|
ещё я должен осудить комментарии на русском, поскольку Дмитриевич говорил, всё на английском писать |
|
если мне не изменяет память, Дмитриевич хотел возможность в программе |
|
в остальном: |
|
ещё можно придраться, что деление на 0 считается = inf, хотя скорее должно быть не определено и выдавать ошибку |
как бы это странно не звучало, но по IEEE 754 при делении положительных чисел возвращается inf, а при делении отрицательных -inf |
стандарт стандартом, но тебе же никто не мешает при делении проверить второй аргумент на равность нулю и, скажем, кинуть исключение. с точки зрения математики, логичнее так сделать, я считаю |
|
|
||
| void clear() | ||
| { | ||
| TStack s; | ||
| swap(*this, s); | ||
| } | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
почему? при выходе из функции будет вызван деструктор, который уничтожит TStack s (у него к этому моменту будет указатель на старые данные)
|
|
||
| TStack& operator=(const TStack& s) | ||
| { | ||
| if (this == &s) | ||
| return *this; | ||
| TStack tmp(s); | ||
| swap(*this, tmp); | ||
| return *this; | ||
| } | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
тоже будет вызван деструктор у TStack tmp при выходе
| TStack& operator=(TStack&& s) noexcept | ||
| { | ||
| delete[] data; | ||
| sz = 0; | ||
| cap = 0; | ||
| data = nullptr; | ||
| swap(*this, s); | ||
| return *this; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
upd: ещё проверка на самоприсваивание должна быть
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
спорный на самом деле вопрос, потому что нарочно сделать самоприсваивание по rvalue невозможно (rvalue - временный объект, как можно превратить уже существующий объект во временный?). можно конечно напридумывать конструкций вроде st=std::move(st) чтобы сделать самоприсваивание, но это уже что-то на уровне стрельбы из ружья по своим ногам.
к тому же мне кажется в коде уже поздно что-то менять
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
вообще не спорный. в обычном операторе= ты ж делаешь проверку от a = a, тоже ведь выстрел в ногу; почему здесь не сделать от st=std::move(st)? ценой одной проверки исключаешь стрельбу по ногам. на счет поздно: согласен, но, ты Дмитриевича вроде до сих пор не тегнул, хотя уже давно пора
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
в таком случае лучше assert делать (если адрес у rvalue каким-то образом оказался равен адресу объекта, то это явно какой-то баг), ну и я клоню к тому, что такие ситуации естественным образом не возникают.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
даже ассерт лучше, чем ничего. но, я всё же считаю, что надо проверять и возвращать *this. и всякие разработчики stl'ей, в частности, мелкософт, предпочитают таки делать так же.(github.com/microsoft/STL/blob/main/stl/inc/vector строка 740)
|
@ValentinV95, код готов к проверке |
| TStack<int> s; | ||
| s.push(42); | ||
| ASSERT_FALSE(s.isEmpty()); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Вроде всё верно (извиняюсь, за то что долго не давала никакую реакцию, так как я не нашла ошибок, не считала нужным об этом писать)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
та же причина не активности
ValentinV95
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Лабораторная и отчет приняты.


No description provided.