从向量中删除取消引用的元素

Posted

技术标签:

【中文标题】从向量中删除取消引用的元素【英文标题】:Deleting dereferenced elements from vector 【发布时间】:2012-02-16 00:42:37 【问题描述】:

我使用 new 创建了对象,但是在将它们添加到向量之前取消了对它们的引用。尽管在互联网上拖网,但我无法弄清楚如何在这些项目上调用删除。我只想使用我不想(例如)使用 Boost 库的标准 C++ 和 STL 来做到这一点。

如您所见,a、b 和 c 失去了作用域,剩下的就是我认为是向量中的副本。我该如何删除这些。我不想在数组中存储指针,因为我需要向 API 函数传递一个双精度数组。

请人 - 我如何删除这些对象?

#include <iostream>
#include <vector>

using namespace std;

vector<double> vectorDouble;
void createObjects();

void createObjects() 
    double* a=new double(13);
    double* b=new double(14);
    double* c=new double(15);
    //a,b and c are not contiguous memory blocks
    cout << "memory location of a: " << a << endl;
    cout << "memory location of b: " << b << endl;
    cout << "memory location of c: " << c << endl;

    vectorDouble.push_back(*a);
    vectorDouble.push_back(*b);
    vectorDouble.push_back(*c);


int main() 
    createObjects();
    //the memory addresses are contiguous 8 byte chunks
    cout << "vector memory at 0: " << &(vectorDouble[0]) << endl;
    cout << "vector memory at 1: " << &(vectorDouble[1]) << endl;
    cout << "vector memory at 2: " << &(vectorDouble[2]) << endl;

    //get pointer to the 2nd element
    double *P=&(vectorDouble[1]); 

    //dereference and look inside - two memory locations both contain the value 14
    cout << "vector Pointer P ["<< P <<"] contains " << *P <<endl;

    //Which should I call delete on? I have lost reference to the original pointers.
    //How should I call delete on the vector?

    cout << "deleting pointer that references 2nd vector element" << endl;
    delete P; //********* CRASH **********
    cout << "Done deleting" << endl;

【问题讨论】:

【参考方案1】:

您需要删除的对象不在向量中,因为您的向量元素不是用 new 创建的。当您在 push_back 中使用取消引用运算符时,您只是将 malloc 的 double 的副本而不是实际分配的 double 传递给向量。

您实际上只是在泄漏它们 - 您的代码可以在不分配双精度的情况下运行良好:

void createObjects() 
    vectorDouble.push_back(13);
    vectorDouble.push_back(14);
    vectorDouble.push_back(15);

【讨论】:

【参考方案2】:

正如每个人所指出的,没有任何理由在您的程序中调用new

void createObjects() 
    vectorDouble.push_back(13);
    vectorDouble.push_back(14);
    vectorDouble.push_back(15);

但是,假设您确实有理由致电new。 (我无法想象它可能是什么,但让我们假设你是个天才)。以下是你的做法:

void createObjects() 
    double* a=new double(13);
    double* b=new double(14);
    double* c=new double(15);
    //a,b and c are not contiguous memory blocks
    cout << "memory location of a: " << a << endl;
    cout << "memory location of b: " << b << endl;
    cout << "memory location of c: " << c << endl;

    vectorDouble.push_back(*a);
    vectorDouble.push_back(*b);
    vectorDouble.push_back(*c);

    delete a;
    delete b;
    delete c;

您看,push_back 不会将指针的副本放入向量中,而是将对象的副本放入向量中。一旦你复制了你的对象,那么你的对象的内存就没有持续的作用,并且可以被销毁。

【讨论】:

好的,我调用new的原因是这个程序实际上代表了我要编写的真实程序: 好的,我调用 new 的原因是这个程序实际上代表了我要编写的真实程序:它是 DirectX 程序,我想要一个 D3DX10_SPRITE 数组,它需要传递给API 函数 DrawSpritesBuffered。正如你所指出的,我可以很容易地创建这些对象而不使用 new,这个问题就会消失。但是我应该在堆栈上创建可能占用 20k 的对象吗?【参考方案3】:

函数 createObjects 没有将分配的值放入向量中;它正在输入值,然后 泄漏内存 abc 指向的。来电:

vectorDouble.push_back(*a);

a 指向的值存储在向量中(*a 取消引用指针,您可能已经知道了)。一旦该函数返回,指针就会丢失。您无法从向量中检索它们。您要么需要创建一个指向双精度的指针向量,要么(更有可能)甚至不分配值;只需存储双打。

【讨论】:

【参考方案4】:

我想我有问题,在:

vectorDouble.push_back(*a);
vectorDouble.push_back(*b);
vectorDouble.push_back(*c);

您将 a、b 和 c 作为值传递,因此数组实际上并不包含您创建的变量(这就是为什么它们现在具有不同的内存地址,它们是变量内容的副本!)。然后你可以删除方法内的变量,不要在方法内使用指针或使用双*向量。

【讨论】:

【参考方案5】:

您的泄漏在createObjects() 中,因为std::vector&lt;&gt;::push_back() 复制了它的参数。你应该deletecreateObjects()范围结束前的指针。

也就是说,我不明白您为什么一开始就使用动态分配。如果你能避免这种情况,请这样做(你可以使用像std::unique_ptr&lt;&gt; 这样的智能指针,或者更好的是使用普通的旧doubles)。

【讨论】:

感谢您的回复。我已经修改了我的代码以删除方法末尾的指针。我现在在最后的向量上调用 clear() 。我假设现在没有内存泄漏。请问最后一个问题;我在向量中的双打现在是在堆上还是在栈上? 您根本不需要调用v.clear(),除非您希望从向量中删除所有元素。如果你说在范围内double *a = new double(13),那么在范围结束时你必须说delete a,当然除非你将a传递给另一个声称对a负责的函数或对象,这样它本身就会@987654332 @ 一种。您可以看到这并不简单,这就是为什么在 C++ 中我们总是希望尽可能避免动态分配。我不知道你为什么对v.push_back(13.0) 不满意。 好的,我会选择v.push_back(object)。 Object 不会被声明为指针,也不会使用new。它将在创建它的方法的范围之外持续存在,因为向量已经复制了它并正在管理该副本。这使生活变得更加轻松,因为我不必新建/删除它。我暂时接受我不理解向量是如何管理内存的,但我只能假设当我使用push_back 时,我的静态声明的对象被复制到了堆内存中。感谢您的帮助。

以上是关于从向量中删除取消引用的元素的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法访问/取消引用并查找存储在双指针向量中的元素的值? [关闭]

通过指针、强制转换和取消引用加载向量?

从向量中删除一个元素而不删除之后的元素

分段错误:从二维向量中随机删除元素

从向量中删除元素时如何减小向量的大小?

从向量结构中删除元素[关闭]