C++ Qt5.7的deleteLater()是否取决于操作系统?

C++ Qt5.7的deleteLater()是否取决于操作系统?,c++,windows,qt,qt5,C++,Windows,Qt,Qt5,大家好,我在代码中发现了一个bug,那就是: 我有一个指向QLocalSocket的指针列表,在析构函数中,我用下面的代码关闭并删除它们 for ( int i = 0; i < localSocketsList.size(); i++ ) { if ( localSocketsList.at(i) != NULL ) { localSocketsList.at(i)->close(); localSocketsList.at(i)-&

大家好,我在代码中发现了一个bug,那就是:

我有一个指向QLocalSocket的指针列表,在析构函数中,我用下面的代码关闭并删除它们

for ( int i = 0; i < localSocketsList.size(); i++ )
{
    if ( localSocketsList.at(i) != NULL )
    {
        localSocketsList.at(i)->close();
        localSocketsList.at(i)->deleteLater();
    }
}
for(int i=0;iclose();
localSocketsList.at(i)->deleteLater();
}
}
错误在于,我之前用套接字的disconnected()信号连接了一个插槽,该插槽也用代码删除了它们:

QMutableListIterator<QLocalSocket *> iterator(localSocketsList);
while( iterator.hasNext() )
{
    QLocalSocket * currentLocalSocket = iterator.next();
    if ( currentLocalSocket -> state() == QLocalSocket::UnconnectedState )
    {
        currentLocalSocket -> deleteLater();
        iterator.remove();
    }
}
QMutableListIterator迭代器(localSocketsList);
while(iterator.hasNext())
{
QLocalSocket*currentLocalSocket=iterator.next();
如果(currentLocalSocket->state()==QLocalSocket::UnconnectedState)
{
currentLocalSocket->deleteLater();
iterator.remove();
}
}
好的,现在你可以看到错误,我尝试删除一个指针两次,结果崩溃了。但是,我花了一段时间才发现这个错误,因为我没有在Windows10中观察到崩溃,只有在Windows7中

问题是:Qt5.7的deleteLater()函数是否因操作系统而异?这个问题不应该出现在所有的平台上,因为它是C++运行时错误?< /P> 也许这取决于Qt如何安排作业(我的意思是,在发送信号之前完成for循环)?在这种情况下,作业的时间表是否取决于操作系统?这不应该几乎是“随机的”吗


谢谢大家

在控件返回到事件循环之前多次调用
deleteLater
是有效的:

#include <QtCore>
int main(int argc, char ** argv) {
  QCoreApplication app{argc, argv};
  auto obj = new QObject;
  obj->deleteLater();
  obj->deleteLater();
  connect(obj, &QObject::destroyed, []{ qApp->quit(); });
  return app.exec();
}

您确定它发生在同一事件循环周期中吗?在同一个周期中多次调用它是可以的,因为挂起的事件将被删除,但是如果它不是同一个周期,您将得到崩溃,因为它是一个悬空指针。有趣的是,我不知道我以后可以在同一个周期中调用Delete两次。但是为什么在Windows10中我没有错误?谢谢你的回答。你说的有道理,可能错误是“删除”了列表。但即便如此,为什么我没有在窗口10中看到这个错误?我只是在尝试Windows 7时发现的,因为您的代码是异步的,断开连接通知可能会在不同的时间到达。我很确定Windows版本只会改变发生此错误的概率-如果您对其进行了足够的测试(数百万甚至数十亿个连接),您将在任何版本的Windows上发生此错误。非常感谢;)找出问题出在列表上,而不是双重deleteLater()对我帮助很大
// https://github.com/KubaO/stackoverflown/tree/master/questions/qobject-pointer-list-43986348
#include <QtCore>

class PointerListData : public QObject, public QSharedData {
   Q_OBJECT
public:
   QVector<QObject*> list;
   void removed() { list.removeAll(sender()); }
   void connect(QObject* obj) {
      QObject::connect(obj, &QObject::destroyed, this, &PointerListData::removed);
   }
   void disconnect(QObject* obj) {
      QObject::disconnect(obj, &QObject::destroyed, this, &PointerListData::removed);
   }
};

template <typename T> class PointerList {
protected:
   QExplicitlySharedDataPointer<PointerListData> d;
public:
   PointerList() : d(new PointerListData) {}
   PointerList(const PointerList &other) : d(other.d) {}
   PointerList(PointerList && other) : d(std::move(other.d)) {}
   void append(T* obj) {
      auto connect = !contains(obj);
      d->list.append(obj);
      if (connect)
         d->connect(obj);
   }
   PointerList & operator<<(T* obj) {
      append(obj);
      return *this;
   }
   int removeAll(T* obj) {
      auto n = d->list.removeAll(obj);
      if (n)
         d->disconnect(obj);
      return n;
   }
   bool contains(T* obj) const {
      return d->list.contains(obj);
   }
   void clear() {
      for (auto obj : d->list)
         d->disconnect(obj);
      d->list.clear();
   }

   void moveToThread(QThread* thread) { d->moveToThread(thread); }
   bool isEmpty() const { return d->list.isEmpty(); }
   int size() const { return d->list.size(); }
   using iterator = T**;
   using const_iterator = const T**;
   iterator begin() { return iterator(d->list.data()); }
   iterator end() { return iterator(d->list.data() + d->list.size()); }
   const_iterator begin() const { return const_iterator(d->list.constData()); }
   const_iterator end() const { return const_iterator(d->list.constData() + d->list.size()); }
   constexpr const PointerList& crange() const noexcept { return *this; }
     // see http://stackoverflow.com/q/15518894/1329652
};

int main(int argc, char ** argv) {
   QCoreApplication app(argc, argv);
   PointerList<QMimeData> list;
   {
      QMimeData a;
      QMimeData b;
      list << &a << &b;
      auto list2 = list;
      Q_ASSERT(list2.size() == 2);
      for (auto obj : list.crange())
         qDebug() << obj;
   }
   Q_ASSERT(list.isEmpty());

}
#include "main.moc"