0

I have a C++ class that contains a private C array as follows,

class DataObject {
    private:
        double* data_array_;
};

Due to restrictions from other parts in the program that are not shown, I can't use a std::vector<double>, can't use the DataObject constructor to initialize the array (initializer list?), and would prefer not to allocate the array on the heap. As such, I have to initialize the array in an init() function, which takes in the number of array elements as its argument. So far I've tried the following, but unfortunately they don't seem to work:

Attempt 1:

void DataObject::init(unsigned int num_elements) {
    data_array_[num_elements];
}

Attempt 2:

void DataObject::init(unsigned int num_elements) {
    data_array_ = double[num_elements];
}

Thus, I was wondering if there's another way to initialize a stack allocated private C array given the above restrictions.

10
  • 5
    This is pure C++ question. There are no stack-allocated variable length arrays in C++. What you want cannot be done, period. Commented Jan 8, 2021 at 6:56
  • 1
    Given that the member is a pointer, and you don’t know the number of elements at compile time, you have no choice but to allocate the array dynamically at runtime. But why can’t you use the constructor for that? At least use the constructor to initialize the pointer to null, in case the destructor is called to free the array before init() is called. And don’t forget to follow the Rule of 3/5/0 to manage the array correctly. Commented Jan 8, 2021 at 6:57
  • 2
    Why can't you use a vector<double>? It should be pretty easy to plug-in whereever a double* is needed (just use data_array_.data() in those places). Why don't you want to use the heap? Commented Jan 8, 2021 at 7:05
  • 2
    "Due to restrictions from other parts in the program that are not shown, I can't use a std::vector<double>"... often it is possible, if you interface it properly. But this sounds like an XY-problem to me. What are you trying to solve and why is it a problem? We need way more details. Commented Jan 8, 2021 at 7:42
  • 2
    " due to limitations when performing GPU parallelization" wait what? You do know that accessing main memory from GPU is very slow? So you should copy the data to the GPU memory anyhow. and that's a dynamic allocation. Commented Jan 8, 2021 at 7:44

1 Answer 1

5

I have a C++ class that contains a private C array as follows,

   double* data_array_;

That is not an array. That is a pointer. As such, your class doesn't and cannot "contain" an array at all. It can only point to (element of) an array that is contained somewhere else.

If you want to point to an automatic array, the only way to do that is to pass (pointer, reference or span to the) array as an argument. Example:

void DataObject::init(double* data_array_, std::size_t num_elements) {
    this->data_array_ = data_array_; this is becom
    this->num_elements = num_elements;
}

void foo() {
    constexpr std::size_t num_elements = 42;
    double data_array_[num_elements];

    DataObject example{};
    example.init(data_array_, num_elements);
}

Note that as a referential type, you must be very careful to keep the pointed array alive at least as long as the DataObject which points to it is alive. Otherwise the pointer will be left dangling. Also note that the class is becoming to look like a limited re-implementation of std::span with dynamic extent. It might be better to just use that instead.

If you need DataObject to control the lifetime of the array (which will be safer since you can avoid dangling), and the size of the array is determined at runtime, then dynamic allocation is your only option (C++ doesn't have flexible array members that C does). If you cannot use std::vector, then I recommend using another implementation of the same datastructure. That said, I suspect that it may be possible that you're mistaken in your assumption that you cannot use std::vector.

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

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.