0

I am converting a vector of doubles to an array of doubles as seen here:

The difference is, that I want to return the pointer a as a function parameter:

void getArray(double* a)
{
    std::vector<double> v;
    a = &v[0];
}

So my question is, when does the memory of a gets deallocated? Or do I have to call delete[] a by myself, which seems strange since I did't allocate the memory with new. I have read the comments to the above mentioned answer but it still isn't clear to me.

Community
  • 1
  • 1
rkgghz
  • 456
  • 8
  • 19
  • 3
    `a` will point to garbage, once `v` is out of scope, there is nothing to delete – 463035818_is_not_an_ai Jun 20 '16 at 15:38
  • As you see there ... is no function call involved. –  Jun 20 '16 at 15:41
  • @DieterLücking what do you mean? Is not destructor a function? – Basilevs Jun 20 '16 at 15:42
  • @Basilevs I think they mean that no function is explicitly called by the programmer. – Alyssa Haroldsen Jun 20 '16 at 15:43
  • 2
    The memory of `a` is deallocated as soon as the function returns, because `a` is a pointer to a vector's element and ´v´ is local to the function. – chema989 Jun 20 '16 at 15:44
  • 3
    Also, next to the UB, from c++11 on, the less hackish version is `v.data()` instead of `&v[0]`, see http://stackoverflow.com/a/10740171/104774 – stefaanv Jun 20 '16 at 15:45
  • 2
    "I am converting a vector of doubles to an array of doubles" - Why? – Jesper Juhl Jun 20 '16 at 15:48
  • 1
    Anyway, forget about the `getArray` function, just use vectors in your program and use `v.data()` where a vector can't be used (e.g. C interface) making sure that the data used is within the timeline of the vector, which is not the case in your example as already mentioned in the answer of Andrew. – stefaanv Jun 20 '16 at 15:51
  • [Return a pointer to array from a function in C++?](http://stackoverflow.com/q/30448688) – Basilevs Jun 20 '16 at 15:53
  • 1
    Possible duplicate of [Pointer to local variable](http://stackoverflow.com/questions/4570366/pointer-to-local-variable) – Basilevs Jun 20 '16 at 15:53
  • Thanks for all the comments. I need to convert the vector to an array because the function is part of (C interface) DLL that is called by a LabView VI which doesn't know `vectors`. – rkgghz Jun 20 '16 at 15:56
  • @rkgghz: and would passing v.data() be a reasonable solution then? After all, that's what is it there for. – stefaanv Jun 20 '16 at 15:58
  • @ stefaanv : I don't think so. Instead I will copy each element to a `new` array and pass that pointer. Then the caller has to delte it. – rkgghz Jun 20 '16 at 16:07

4 Answers4

6

The memory pointed to by a gets deallocated when the vector v is destructed. In this case, that's at the end of the function getArray.

Alyssa Haroldsen
  • 3,652
  • 1
  • 20
  • 35
  • @Basilevs Depends what OP is trying to do. When *do* you want the memory destructed? Who should be managing this? – Alyssa Haroldsen Jun 20 '16 at 15:42
  • 2
    @Basilevs A good approach to memory management would be to keep the vector as a vector and have that manage the memory instead of taking upon oneself to manually manage it. It really depends on the end goal. Sample usage for something that shouldn't be done could suggest that that's the right thing to do. A modern C++ programmer should try to avoid raw pointers. – Alyssa Haroldsen Jun 20 '16 at 15:51
1

Don't do this:

void getArray(double* a)
{
    std::vector<double> v;
    a = &v[0];
} // The vector is destroyed here, and the memory
  // is deallocated.

In any case, you're not modifying the a pointer outside of your function, so you won't get the desired effect.

Instead, return the vector and use it directly. Or, in general, use vectors throughout your code. If you need to pass them in to a function that expects a pointer to an array, you can pass &v[0] there. Such a function usually expects the size too. For this, pass v.size(). You can do this safely as long as that function doesn't take ownership, or deallocate the memory.

Note, also, that a vector declared as std::vector<double> v; does not have a size, so attempting to access the first element, as in v[0] is also undefined behaviour. At the very least, you need to give the vector a size (pass a size to its constructor) to ensure some memory is allocated. You should always make sure the vector has some allocated memory before indexing into it, including when trying to take the address of the first element.

What you probably want to do is:

std::vector<double> getArray() {
  std::vector<double> v = /* some sane initialisation */;
  return v;
}

// some time later, assuming a function:
//   void do_something(double* a, size_t n);
// ...

std::vector<double> v = getArray();
if (v.size()) {
  do_something(&v[0], v.size());
} else {
  // fail gracefully
}
Andrew
  • 5,212
  • 1
  • 22
  • 40
1

This implementation would invoke undefined behavior because v is local:

void getArray(double* a)
{
    std::vector<double> v;
    a = &v[0]; // would be a UB for returning the pointer to internals of a local variable.
}

However, the caller will never see any effect of this, because modifications to a stay local to getArray function.

If you want to make an array out of a vector, allocate a new array, use std::copy to copy the content into it, and return the array to the caller. Make sure the callers call delete[] on the result once they are done with the copyL

double *getArray(const vector<double>& v) {
    double *res = new double[v.size()];
    std::copy(v.begin(), v.end(), res);
    return res;
}

The caller should use it as follows:

vector<double> data;
data.push_back(...);
... // populate the vector
double *tmp = getArray(data);
... // Use the array
delete[] tmp; // Avoid memory leaks
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
1

when does the memory of a gets deallocated?

The a pointer itself is a local variable, so it is deallocated at the end of its scope.

a points to the memory allocated by the vector v. The pointed memory is deallocated in the destructor of v (The memory may also be deallocated if objects are added to or removed from the vector). And because v is a local variable, it is destroyed at the end of scope.

Or do I have to call delete[] a by myself,

No, because the memory is owned by the vector object, but also because

which seems strange since I did't allocate the memory with new.

Exactly. You didn't call new[], so you don't call delete[].


Note that v[0] has undefined behaviour because the vector is empty.

eerorika
  • 232,697
  • 12
  • 197
  • 326