Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I force std::vector to leave a memory leak?

Tags:

c++

swig

Can I force std::vector to not deallocate its memory after the vector goes out of scope?

For example, if I have

int* foo() {
    std::vector<int> v(10,1); // trivial vector
    return &v[0];
}

int main()
{
    int* bar = foo();
    std::cout << bar[5] << std::endl;
}

There is no guarantee that the values will still be accessible here.

I am currently simply doing this

int* foo() {
  std::vector<int> v(10,1);
  int* w = new int[10];
  for (int i=0; i<10; i++) {
    w[i] = v[i];
  }
  return w;
}

but it is a little wasteful to repopulate a whole new array. Is there a way to force std::vector to not delete its array?

Note: I am not returning the vector itself because I am interfacing c++ with python using SWIG, and ARG_OUTVIEW_ARRAY requires a raw pointer and, in fact, an intentional memory leak. I would still however like to be able to make use of vector features while constructing the data itself.

like image 262
jxz12 Avatar asked May 14 '19 10:05

jxz12


2 Answers

It is possible but you should never do it. Forcing a vector to leave memory leak is a terrible idea and if you need such a thing then you need to re-think your design. std::vector is a resource managing type whose one of the main goals is to ensure that we don't have a leak. Never try to break that.

Now, to answer your specific question: std::vector takes an allocator type as second template parameter which is default to std::allocator<T>. Now you can write a custom allocator that doesn't release any memory and use that with your vector. Writing a custom allocator is not very trivial work, so I'm not going to describe that here (but you can Google to find the tutorials).

If you really want to use custom allocator then you must ensure that your vector never triggers a grow operation. Cause during growing capacity the vector will move/copy data to new location and release the old memories using the allocator. If you use an allocator that leaks then during growing you not only retain the final data, but also retain the old memories which I'm sure that you don't want to retain. So make sure that you create the vector with full capacity.

like image 167
taskinoor Avatar answered Sep 20 '22 16:09

taskinoor


The vector is desiged to prevent leaks.

But if you want to shoot yourself in the foot, it's possible. Here's how you prevent the vector from deallocating its internal array:

int *foo()
{
    std::vector<int> v(10,1);

    int *ret = v.data();
    new (&v) std::vector<int>; // Replace `v` with an empty vector. Old storage is leaked.
    return ret;
}

As the other answers say, you should never do it.

like image 44
HolyBlackCat Avatar answered Sep 17 '22 16:09

HolyBlackCat