【发布时间】:2022-06-11 01:03:19
【问题描述】:
我一直在用 C++ 编写自己的队列。 问题在于它有一个名为 Queue::Pop() 的函数,该函数调用队列中第一项的析构函数,该函数由名为 _First 的索引跟踪,然后 _First 递增,_Length 递减。 当正常编译时,它按预期执行,但是当添加 -O1 标志时,它开始表现得很奇怪并且没有正确调用对象的析构函数。 析构函数中的打印发生但 Id 未设置为 -1。 结果,当队列超出范围时,内存被 delete[] 编辑并再次调用析构函数,这是无效代码,因为如果它是文件描述符,它将被关闭两次。 这是弹出功能:
void Queue::Pop()
{
std::destroy_at(std::addressof(Head()));
--_Length;
_First = (_First + 1) % Capacity();
}
T &Head()
{
AssertEmpty();
return _Content.Content()[_First];
}
我正在用这样的方式测试我的代码:
class Messenger
{
public:
int Id = -1;
Messenger() = default;
Messenger(size_t id) : Id(id)
{
std::cout << Id << " Constructed" << std::endl;
}
Messenger(Messenger &&Other) : Id(std::move(Other.Id))
{
Other.Id = -1;
}
Messenger &operator=(Messenger &&Other)
{
Id = std::move(Other.Id);
Other.Id = -1;
return *this;
}
~Messenger()
{
if (Id != -1)
{
std::cout << Id << " Destructed" << std::endl;
Id = -1;
}
}
};
以及主要功能:
int main(int argc, char const *argv[])
{
Queue<Messenger> Queue;
Queue.Add(1);
Queue.Add(2);
Queue.Pop();
Queue.Pop();
std::cout << "Finished" << std::endl;
return 0;
}
这里是我得到的输出:
1 Constructed
2 Constructed
1 Destructed
2 Destructed
Finished
2 Destructed
1 Destructed
如您所见,打印完成后,无需打印任何其他内容。
【问题讨论】:
-
顺便说一句,这只发生在 gcc 而不是 clang!
标签: c++ gcc optimization memory queue