4

I want to create a std::vector<float> vpd which will be a reference to float*.

float * old = new float[6];
for (int i = 0; i < 6; i++)
{
    old[i] = i;
}
vector<float> vpd(6);
auto refasd = &*vpd.begin();
*refasd = *old;
vpd[0] = 23;
cout << old[0] << endl;

How should I modify the code, if I want get 23 from cout?

3
  • Are you maybe looking for this: stackoverflow.com/questions/2434196/… Commented Nov 21, 2018 at 10:52
  • Is it about telling the vector to use your "preallocated" buffer instead of the one a vector manages internally, or is it just that you want to refer to to the vector's internal buffer in terms of a float*-type? Commented Nov 21, 2018 at 10:52
  • maybe you meant vpd[0] = 23; *old = *refasd; ? Commented Nov 21, 2018 at 10:52

5 Answers 5

5

You can't. std::vector is not designed to take ownership of a raw pointer.
Maybe you can make do with std::unique_ptr<float[]>, but the better solution is to directly use std::vector.

Sign up to request clarification or add additional context in comments.

Comments

5

As alternative, you might use std::span (C++20)

float* old = new float[6];
std::iota(old, old + 6, 0);
std::span<float> vpd(old, 6);
vpd[0] = 23;
std::cout << old[0] << std::endl;
delete[] old;

2 Comments

Plus one from the future. Does span own the memory, i.e. is the delete[] intentionally missing?
Span does not own the memory if I'm not mistaken, so yeah, a delete[] is missing.
4

You could also create a vector of std::reference_wrapper objects that refer to the original float array - may that be std::vector<float> or a newed float*. An example:

vector<std::reference_wrapper<float>> vpd(old, old + 6); // ¹

vpd[0].get() = 23.f;

cout << old[0] << endl; // prints 23

¹) Thanks to @StoryTeller for pointing out that vpd can be directly initialized.

2 Comments

I'm not sure you need std::transform. IIRC std::vector<std::reference_wrapper<float>> vpd(old, old + 6); should work out of the box.
@StoryTeller True, that's a nice improvement!
2

As std::vector has its own memory structure you cannot map vector<float> or even vector<float*> to an array of float. However you can map each vector item to an array one.

float* old = new float[6];
for (int i = 0; i < 6; i++)
{
    old[i] = i;
}
vector<float*> vpd(6);
int i = 0;
for (auto it = vpd.begin(); it != vpd.end(); it++)
{
    *it = &old[i++];
}
*vpd[0] = 23;
*vpd[2] = 45;
cout << old[0] << endl << old[2] << endl;    

Output

23
45

14 Comments

You ruined your cache locality by doing this, though
@LightnessRacesinOrbit cold you please explain in more details?
@LightnessRacesinOrbit the link is cool in design context however I still don't see the relation with reusing of some memory piece accessed by pointers.
The entire article is about how indirection in your containers reduces performance by thwarting your CPU's cache. Pointers in contiguous containers should be avoided unless necessary for some goal. A contiguous set of data means the cache will function properly when you obtain the first element; that is, the second and third and maybe more will already be ready for reading. If you are extracting pointers and have to dereference each one, the odds of that information being in cache each time are low (unless the "real" data is nearby) so you will have lots of cache misses. This is expensive.
Now you're talking about the cost of creating those elements, not the cost of accessing them. But the answer is still yes.
|
0

Depending on version of C++ you'll have some options (if I understand the problem): if you have an older c++ version then c++11 I would in this case declear std::vector as:

// then you really need to make sure u delete the memory as well
std::vector<float*> vpd(6); 

If however you got c++11 or higher I would use either std::share_ptr or std::unique_ptr depending on if you would like to share the memory space or not. Either this will ensure the memory is deleted by it self without having to do a "delete float*;" which is nice. You can read about std::shared_ptr at: https://en.cppreference.com/w/cpp/memory/shared_ptr and std::unique_ptr at: https://en.cppreference.com/w/cpp/memory/unique_ptr

// For unique_ptr
std::vector<std::unique_ptr<float>> vpd(6);
// for std::shared_ptr
std::vector<std::shared_ptr<float>> vpd(6);

I would say that if you can then use unique_ptr rather then shared_ptr due to shared_ptr has som extra komplexitity within to be make sure the memory not used before deleteing memory space.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.