简体   繁体   English

将向量复制到类的向量成员中

[英]Copying a vector into a vector member of a class

I have a class with a vector member.我有一个带有向量成员的类。 I have accessors to set/get the value of the vector.我有访问器来设置/获取向量的值。

typedef vector<int> vint_t;

class MyVector {
  public:
    MyVector(const vint_t & v) : _vint(v) {};

    size_t set(const vint_t & v) {
        _vint = v;  // Will this leak memory in the old location of _vint?
        const size_t n = v.size();
        return n;
    }

    const vint_t & get() {
        return _vint;
    }

  private:
    vint_t _vint;
};

Besides the fact that set correctly sets the contents of _vint (verified with code below, operator<< suitably overloaded), would set leak the memory at the old location of _vint ?除了set正确设置_vint的内容(用下面的代码验证, operator<<适当重载)之外,还会在_vint的旧位置set泄漏内存吗?

vint_t v1 = { 1, 4, 10, 2 };
MyVector mv1(v1);
cout << mv1.get() << endl;
vint_t v3 = { 8, 1, 4, 10, 2 };
mv1.set(v3);
cout << mv1.get() << endl;

No , it does not leak memory, this because the standard containers are programmed sanely.,它不会泄漏内存,这是因为标准容器的编程很合理。 The assignement, in this case, just call the copy constructor of each element of the vector on the "right of =" and copy it on the vector on the "left of =".在这种情况下,赋值只是调用“=”右侧向量的每个元素的复制构造函数,并将其复制到“=”左侧的向量上。 Before this kind of assignement the vector on the "left of =" call the destructor of all the object.在这种赋值之前,“=”左边的向量调用所有对象的析构函数。

So if a memory leak happens it's due to the leak on the object argument of the vector template.因此,如果发生内存泄漏,那是由于向量模板的对象参数泄漏。

would set leak the memory at the old location of _vint?会在_vint 的旧位置设置泄漏内存吗?

No. The memory location of _vint didn't change in the first place.不会_vint的内存位置一_vint并没有改变。 Furthermore, the assignment operator of std::vector is not specified to leak memory (nor is any operation of any standard container).此外, std::vector的赋值运算符未指定为泄漏内存(任何标准容器的任何操作也未指定)。

Of course, if the objects stored in the vector were handles to some resource, then those would leak if the handle is removed without releasing the resources.当然,如果存储在向量中的对象是某个资源的句柄,那么如果在不释放资源的情况下删除句柄,这些对象就会泄漏。 In your example you've used arbitrary integer values, so they appear to not be resource handles.在您的示例中,您使用了任意整数值,因此它们似乎不是资源句柄。

size_t set(const vint_t & v) {
    _vint = v;  // Will this leak memory in the old location of _vint?
}

There is no way this can leak memory unless std::vector would be terribly broken.除非std::vector被严重破坏,否则这不可能泄漏内存。 In general after a = b;一般在a = b; the object a is still the same object.对象a仍然是同一个对象。 Only the value gets copied.只有值被复制。 You are calling std::vector::operator= which isn't broken.您正在调用未损坏的std::vector::operator=

Since _vint is an object, it doesn't "change location".由于_vint是一个对象,它不会“改变位置”。 Pointers don't change location either, but can cause memory leaks if you allocate extra memory via malloc or new .指针也不会改变位置,但如果您通过mallocnew分配额外的内存,则会导致内存泄漏。

In your example though, you are neither using pointers nor allocating new memory.但是,在您的示例中,您既不使用指针也不分配新内存。 If you aren't allocating new memory, there will be no memory leaks, you will be using only as much memory as necessary and all of it will be accounted for when exiting a scope (like a function).如果您不分配新内存,则不会有内存泄漏,您将只使用必要的内存,并且在退出作用域(如函数)时所有这些都将被考虑在内。 This does not account for indefinitely nesting scopes, eg recursive functions, but you are not working with those either.这不考虑无限嵌套的范围,例如递归函数,但您也没有使用它们。

The point is, you are working with an object and assigning a value to it.关键是,您正在处理一个对象并为其分配一个值。 The value is changed, but there is no "old location".该值已更改,但没有“旧位置”。 No memory leaks here.这里没有内存泄漏。

_vint = v

This is a copy assign operation , so the content of v are copied to _vint , but you don't delete or create any object, so there is no possible leak of memory.这是一个复制赋值操作,所以v的内容被复制_vint ,但你没有删除或创建任何对象,所以没有可能的内存泄漏。 Also, remember that leaks of memory mostly happen when you are working with pointers, and you are not.另外,请记住,内存泄漏主要发生在使用指针时,而实际上并非如此。

This is not an answer to the question, but I do see two dangers in this code.这不是问题的答案,但我确实在这段代码中看到了两个危险。

First第一的

size_t set(const vint_t & v) {
    _vint = v;  // Will this leak memory in the old location of _vint?
}

The function returns size_t but has no return statement.该函数返回size_t但没有 return 语句。 I would expect compilers to complain about this.我希望编译器会抱怨这个。 The function should probably return void .该函数可能应该返回void

const vint_t & get() {
    return _vint;
}

Use this with caution.请谨慎使用。 You need to be careful that the lifetime of the MyVector object is not shorter than any reference returned by get .您需要注意MyVector对象的生命周期不短于get返回的任何引用。 For instance, a short contrived example:例如,一个简短的人为例子:

MyVector* mvp = new MyVector(v1);
const vint_t& vref = mvp->get();
delete mvp;
// ...
std::cout << vref << '\n'; // oh dear

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM