Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ QT图像查看器示例,可能的内存泄漏?_C++_Qt - Fatal编程技术网

C++ QT图像查看器示例,可能的内存泄漏?

C++ QT图像查看器示例,可能的内存泄漏?,c++,qt,C++,Qt,QT文档网站上的包含以下代码段: ImageViewer::ImageViewer() : imageLabel(new QLabel) , scrollArea(new QScrollArea) , scaleFactor(1) { imageLabel->setBackgroundRole(QPalette::Base); imageLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ign

QT文档网站上的包含以下代码段:

ImageViewer::ImageViewer()
   : imageLabel(new QLabel)
   , scrollArea(new QScrollArea)
   , scaleFactor(1)
{
   imageLabel->setBackgroundRole(QPalette::Base);
   imageLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
   imageLabel->setScaledContents(true);

   scrollArea->setBackgroundRole(QPalette::Dark);
   scrollArea->setWidget(imageLabel);
   scrollArea->setVisible(false);
   setCentralWidget(scrollArea);

   createActions();

   resize(QGuiApplication::primaryScreen()->availableSize() * 3 / 5);
}
其中
imageLabel
scrollArea
分别是指向
QLabel
QScrollArea
的指针成员

我理解在
scrollArea->setWidget(imageLabel)行中滚动区域拥有imageLabel指针的所有权,并在需要时将其删除。同样适用于
setCentralWidget(滚动区域)其中窗口拥有滚动区域的所有权

但是,在构建过程中,如果
imageLabel
创建成功,但是
scrollArea
创建失败,那么
imageLabel
是否会泄漏


如果是,解决这个问题的标准方法是什么?

我认为有两种方法:

1。使用智能指针而不是原始指针(例如
QPointer


更多细节可能会被发现(道德4是关于你的问题)

现在就这样解决它:

ImageViewer::ImageViewer()
    : scaleFactor(1)
{
   //Manage pointers with unique_ptr until it's time to transfer ownership. 
   auto uniqueImageLabel = std::make_unique<QLabel>();
   auto uniqueScrollArea = std::make_unique<QScrollArea>();

   //Copy pointers to members for access as per normal.
   imageLabel = uniqueImageLabel.get();
   scrollArea = uniqueScrollArea.get(); 

   imageLabel->setBackgroundRole(QPalette::Base);
   imageLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
   imageLabel->setScaledContents(true);

   scrollArea->setBackgroundRole(QPalette::Dark);
   //ScrollArea now takes ownership of image label. 
   scrollArea->setWidget(uniqueImageLabel.release());
   scrollArea->setVisible(false);
   //Window now takes ownership of scroll area.
   setCentralWidget(uniqueScrollArea.release());

   createActions();

   resize(QGuiApplication::primaryScreen()->availableSize() * 3 / 5);
}
ImageViewer::ImageViewer()
:scaleFactor(1)
{
//使用unique_ptr管理指针,直到转移所有权。
auto uniqueImageLabel=std::make_unique();
auto uniqueScrollArea=std::make_unique();
//将指针复制到成员以按正常方式访问。
imageLabel=uniqueImageLabel.get();
scrollArea=uniqueScrollArea.get();
imageLabel->setBackgroundRole(QPalette::Base);
imageLabel->setSizePolicy(QSizePolicy::忽略,QSizePolicy::忽略);
图像标签->设置缩放内容(真);
scrollArea->setBackgroundRole(QPalette::Dark);
//ScrollArea现在拥有图像标签的所有权。
scrollArea->setWidget(uniqueImageLabel.release());
滚动区域->设置可见(假);
//窗口现在拥有滚动区域的所有权。
setCentralWidget(uniqueScrollArea.release());
createActions();
调整大小(QGuiApplication::primaryScreen()->availableSize()*3/5);
}

好吧,这可能是Qt的一个总体问题,因为它不是完全异常安全的

从实用的角度来看,除非您创建关键任务应用程序,否则这并不重要。如果滚动区域的构建(即动态分配)失败,那么这意味着发生了非常可怕的事情:所有的内存都耗尽了,甚至不将内存交换到磁盘都有助于解决这个问题。在这种情况下,内存泄漏是您最不关心的问题。您可能会崩溃或完全冻结您的计算机无论如何,重新启动将是必要的

当然,您可以尝试使用智能指针解决部分代码,但它仍然可能在Qt库本身中留下大量漏洞。如果你的内存完全用完,你的程序无论如何都会失灵

因此,除非您创建真正防弹的关键任务应用程序,否则您可能不需要关心这种情况。如果我是你,我会更关心系统性内存泄漏,在正常情况下你会忘记释放内存

除非创建任务关键型应用程序,否则不必担心内存不足。这是一个“vis maior”,当这种情况出现时,你几乎无法采取任何措施来保护你的应用程序。好消息是,我们大多数人在正常情况下从未经历过这种情况

    ImageViewer::ImageViewer()
        : imageLabel(nullptr)
        , scrollArea(nullptr)
        , scaleFactor(1)
    {
        try {
            imageLabel = new QLabel();
            scrollArea = new QScrollArea();
        } catch (std::bad_alloc&) {
            delete imageLabel;
            delete scrollAreal;
        }
        // ...
    }
ImageViewer::ImageViewer()
    : scaleFactor(1)
{
   //Manage pointers with unique_ptr until it's time to transfer ownership. 
   auto uniqueImageLabel = std::make_unique<QLabel>();
   auto uniqueScrollArea = std::make_unique<QScrollArea>();

   //Copy pointers to members for access as per normal.
   imageLabel = uniqueImageLabel.get();
   scrollArea = uniqueScrollArea.get(); 

   imageLabel->setBackgroundRole(QPalette::Base);
   imageLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
   imageLabel->setScaledContents(true);

   scrollArea->setBackgroundRole(QPalette::Dark);
   //ScrollArea now takes ownership of image label. 
   scrollArea->setWidget(uniqueImageLabel.release());
   scrollArea->setVisible(false);
   //Window now takes ownership of scroll area.
   setCentralWidget(uniqueScrollArea.release());

   createActions();

   resize(QGuiApplication::primaryScreen()->availableSize() * 3 / 5);
}