1

For my project I need to store pointers to objects of type ComplicatedClass in an array. This array is stored in a class Storage along with other information I have omitted here.

Here's what I would like to do (which obviously doesn't work, but hopefully explains what I'm trying to achieve):

class ComplicatedClass
{
    ...
}


class Storage
{
    public:
        Storage(const size_t& numberOfObjects, const std::array<ComplicatedClass *, numberOfObjects>& objectArray)
            : size(numberOfObjects),
              objectArray(objectArray)
        {}

    ...

    public:
        size_t size;
        std::array<ComplicatedClass *, size> objectArray;
    
    ...
}


int main()
{
    ComplicatedClass * object1 = new ComplicatedClass(...);
    ComplicatedClass * object2 = new ComplicatedClass(...);
    Storage myStorage(2, {object1, object2});
    
    ...
    
    return 0;
}

What I am considering is:

  1. Using std::vector instead of std::array. I would like to avoid this because there are parts of my program that are not allowed to allocate memory on the free-store. As far as I know, std::vector would have to do that. As a plus I would be able to ditch size.
  2. Changing Storage to a class template. I would like to avoid this because then I have templates all over my code. This is not terrible but it would make classes that use Storage much less readable, because they would also have to have templated functions.

Are there any other options that I am missing?

5
  • 6
    I'm not really sure what you mean by "free-store", but you can pass an allocator to std::vector which is used to allocate the memory it needs internally. Such an allocator can be made to allocate memory wherever you need Commented Dec 21, 2021 at 20:48
  • @UnholySheep Oh, right! I totally forgot about that. I have to look into that, thanks! I thought C++ had "free-store" instead of heap, does it not? Commented Dec 21, 2021 at 20:49
  • Heap is an implementation, by far the most common, of the free store. Commented Dec 21, 2021 at 20:49
  • Oh, right. I forgot that the standard refers to it that way (I've yet to work on a platform where the free-store is something different than the heap, so I completely forgot about that name) Commented Dec 21, 2021 at 20:53
  • I've only seen non-heap free stores in the hands of academics. If any managed to escape into the wild, they were outcompeted and didn't get a chance to breed and destabilize the ecosystem. Commented Dec 21, 2021 at 21:27

2 Answers 2

2

How can I pass and store an array of variable size containing pointers to objects?

By creating the objects dynamically. Most convenient solution is to use std::vector.

size_t size;
std::array<ComplicatedClass *, size> objectArray;

This cannot work. Template arguments must be compile time constant. Non-static member variables are not compile time constant.

  1. I would like to avoid this because there are parts of my program that are not allowed to allocate memory on the free-store. As far as I know, std::vector would have to do that.

std::vector would not necessarily require the use of free-store. Like all standard containers (besides std::array), std::vector accepts an allocator. If you implement a custom allocator that doesn't use free-store, then your requirement can be satisfied.

Alternatively, even if you do use the default allocator, you could write your program in such way that elements are inserted into the vector only in parts of your program that are allowed to allocate from the free-store.

I thought C++ had "free-store" instead of heap, does it not?

Those are just different words for the same thing. "Free store" is the term used in C++. It's often informally called "heap memory" since "heap" is a data structure that is sometimes used to implement it.

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

Comments

0

Beginning with C++11 std::vector has the data() method to access the underlying array the vector is using for storage.

And in most cases a std::vector can be used similar to an array allowing you to take advantage of the size adjusting container qualities of std::vector when you need them or using it as an array when you need that. See https://stackoverflow.com/a/261607/1466970

Finally, you are aware that you can use vectors in place of arrays, right? Even when a function expects c-style arrays you can use vectors:

vector<char> v(50); // Ensure there's enough space
strcpy(&v[0], "prefer vectors to c arrays");

6 Comments

std::vector has always had a contiguity guarantee, making &v[0] usable anywhere a pointer is needed (it's not new with C++11). And that remains a better option than data(), because it works on both vectors and strings.
The underlying array of the vector would still be allocated on the heap, right? Unless I use a custom allocator.
@Agiltohr yes the underlying array would still be located where ever the std::vector allocator is using to allocate memory. I'm curious why the memory location where the array is allocated matters. Can you provide details about this requirement in your posted question by editing it? It sounds like parts of your application are free to do so and others aren't. Is this some type of safety standard to prevent an out of memory event on an allocation causing an application crash or something else that you could explain? You can treat a std::vector as an array when you need to or as a container.
@RichardChambers It is a realtime context for audio processing. It is typical that heap allocations during the processing is prohibited, one needs to do any necessary allocations beforehand because allocations on the heap are too slow. I need to pass around some objects (that I've allocated before the processing started) to functions but which objects and how many I need to pass may be chosen at runtime. I could allocate the vectors of all possible combinations on the heap beforehand but that doesn't seem very practical.
@Agiltohr With std::vector you can use the container methods to pre-allocate a vector of the size needed on the heap or free store and then use the resulting vector as an array where ever you need it without having to do any more allocations. And you can probably pick times to resize the vector when using the heap or free store will not matter. Or you can write your onw allocator for speed. I'm curious if you have written your own version of new for object construction?
|

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.