c++ - 混合在堆上和堆栈上创建的 vector 对象

标签 c++ heap-memory new-operator

我有一个相当简单的问题,但无法解决。

假设我有这段代码:

#include <iostream>
#include <vector>
using namespace std;

class B
{
public:
    B(const int& val) {this->val = val;}
    int val;
};

class A
{
public:
    A() {}
    void Set(B& ptb)
    {
        ptBs.push_back(&ptb);
    }
    void Set(const int& val)
    {
        ptBs.push_back(new B(val));
    }
    std::vector<B*> ptBs;
};

int main()
{
    A* ptA = new A();
    ptA->Set(B(10));
    ptA->Set(38);

    for (int i=0; i<ptA->ptBs.size(); i++)
        cout << ptA->ptBs[i]->val << endl;

    delete ptA;

    system("pause");
    return 0;
}

输出结果为:

10
38

但我认为如果我不使用通过此方法创建的数组元素调用 delete,则 void Set(const int& val) 中会发生内存泄漏。

我怎么说,std::vector 的哪些元素是在堆上创建的,所以我可以像这样在 ~A() 析构函数中释放内存:

~A()
{
    for (int i=0; i<ptBs.size(); i++)
        delete ptBs[i];
}

我是否必须删除通过临时新操作调用创建的 vector 元素?

可能我在这里没有看到非常简单的东西,但我的应用程序中确实需要此功能。

附言。 10和38只是一个简单的例子。 Set 函数可以使用不同的参数调用数千次。

最佳答案

幸运的是,这一行不会编译:

ptA->Set(B(10));

这是因为 B(10) 是一个构造函数强制转换表达式,它创建一个 B 类型的临时纯右值;纯右值不能绑定(bind)到 void A::Set(B& ptb) 的左值引用 B & 参数。这是 C++ 语言,可以保护您免受将悬空指针存储到临时值的后果。

A 按值存储其 B 项目通常更有意义:

std::vector<B> Bs;

关于c++ - 混合在堆上和堆栈上创建的 vector 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14774134/

相关文章:

c++ - 如何将 CString 转换或转换为 LPWSTR?

c++ - 为什么我们需要模板模板参数的模板特化

c++ - 使用 boost::ref 的段错误

c++ - 写入 COM 端口

c - C 中的激活记录是在堆栈还是堆上创建的?

c++ - 为什么 std::equal_to 会导致动态分配?

java - 在 Java 中处理大字符串时出现 StringBuilder 内存不足错误

javascript - "new"在 JavaScript 中的作用

c++ - 何时包含内置类型和运算符的 header ?

c++ - 如何分配线程本地存储?