开发者

QScopedArrayPointer guarding my data but it is still leaking

开发者 https://www.devze.com 2023-02-24 21:36 出处:网络
#include <QScopedArrayPointer> #include <QDebug> #include <stdexcept> class MyData{ public:
#include <QScopedArrayPointer>
#include <QDebug>
#include <stdexcept>

class MyData{
public:
  MyData() {
    qDebug() << "Construct a data";
  }

  ~MyData() {
    qDebug() << "Delete a data";
  }

private:
  float internal_data_;
};

class MyClass{
  QScopedArrayPointer<MyData> data_;
public:
  MyClass(){
    data_.reset(new MyData[10]);

    throw std::runtime_error("Shit happens");
  }
};

int main(int argc, char *argv[])
{
    MyClass a_class;

    return 1;
}

Running this program will output:

Construct a data 
Construct a da开发者_C百科ta 
Construct a data 
Construct a data 
Construct a data 
Construct a data 
Construct a data 
Construct a data 
Construct a data 
Construct a data 
terminate called after throwing an instance of 'std::runtime_error'
  what():  Shit happens
The program has unexpectedly finished.

Right before the runtime_error, the variable data_ has been fully created. Why is it that data_ destructor not called?

Also, how do I make sure memory does not leak in this case?


I think the issue is that your exception is uncaught and is being handled by the terminate handler. Since there is no catch to handle the exception, there is no way for the compiler to know how much to "unroll". If you catch the exception, then destruction occurs. You can then of course re-throw it if you like, for example:

#include <QScopedArrayPointer>
#include <QDebug>
#include <stdexcept>

class MyData{
public:
  MyData() {
    qDebug() << "Construct a data";
  }

  ~MyData() {
    qDebug() << "Delete a data";
  }

private:
  float internal_data_;
};

class MyClass{
  QScopedArrayPointer<MyData> data_;
public:
  MyClass(){
    data_.reset(new MyData[10]);

    throw std::runtime_error("Shit happens");
  }
};

int main(int argc, char *argv[]) {
    try {
        MyClass a_class;
    } catch (const std::runtime_error &) {
        throw;
    }
}

Outputs the following:

$ ./test2 
Construct a data 
Construct a data 
Construct a data                                                                                                                     
Construct a data                                                                                                                     
Construct a data                                                                                                                     
Construct a data                                                                                                                     
Construct a data 
Construct a data 
Construct a data 
Construct a data 
Delete a data 
Delete a data 
Delete a data 
Delete a data 
Delete a data 
Delete a data 
Delete a data 
Delete a data 
Delete a data 
Delete a data 
terminate called after throwing an instance of 'std::runtime_error'
  what():  Shit happens
Aborted
0

精彩评论

暂无评论...
验证码 换一张
取 消