2

I am trying to initialize an array of size n based off the input argument of my constructor. This works:

//Inside Header
class runningAverage{
    private:
        byte n;
        float array[10];
    public:
        runningAverage(byte);
};

//Inside .cpp
runningAverage::runningAverage(byte a){
    n = a;
    for (byte i = 0; i<n; i++) {
        array[i] = 0;
    }
}

and this does not work:

//Inside Header
class runningAverage{
    private:
        byte n;
        float array[];
    public:
        runningAverage(byte);
};

//Inside .cpp
runningAverage::runningAverage(byte a){
    n = a;
    for (byte i = 0; i<n; i++) {
        array[i] = 0;
    }
}

I want to initialize the array so that is the size specified by n. This way I don't waste memory by arbitrarily specifying float array[256] or something like that. Any help is appreciated!

4
  • Also it is worth noting that this is being written for an arduino library! Commented Aug 6, 2014 at 5:57
  • for initializing array you need to pass some value. so when you receive value for n from user, you need to pass that. Commented Aug 6, 2014 at 5:59
  • read about pointers and new & delete in C++, this will allow you to create an array of desired size Commented Aug 6, 2014 at 6:03
  • I know about those things, but I don't see how it relates. Could you write me an example? Commented Aug 6, 2014 at 6:07

3 Answers 3

6

You have to actually allocate the array; and you'll want to use a pointer type, float array[] is not what you think there. As juanchopanza reminds us, you'll also want to either disable the copy constructor and assignment operator, or implement ones that do a proper deep copy.

//Inside Header
class runningAverage{
    private:
        byte n;
        float *array; // <= correct type
    public:
        runningAverage(byte);
        ~runningAverage(); // <= you'll need a destructor to cleanup
    private:
        runningAverage(const runningAverage &);
        runningAverage & operator = (const runningAverage &);
};

//Inside .cpp
runningAverage::runningAverage(byte a){
    array = new float[n]; // <= allocate array
    n = a;
    for (byte i = 0; i<n; i++) {
        array[i] = 0;
    }
}

// clean up
runningAverage::~runningAverage(){
    delete[] array;
}

However, if you have some dynamic, automatic container at your disposal (e.g. std::vector) you might want to use that instead - then you don't have to deal with copy / assignment / destructor / memory management.

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

6 Comments

Better to also provide copy and assignment operators, or disable those operations.
Wow thanks this solved my problem. Just a couple questions. Do you really need a destructor if it will never be called? And let me get this straight, array is declared as a pointer to a float. then at new float[n], you are allocating memory for the array? also why do you have the square brackets after delete?
What are copy and assignment operators? @juanchopanza
BTW you don't need the loop in the constructor, you can zero-initialize the array elements like this: array = new float[n]();.
@user3912409 "c++ copy constructor and assignment operator". You should get into the habit of always defining a destructor when special cleanup is needed, for a dozen+ very good reasons.
|
3

If you only know the size at runtime, Jason C's answer is what you want. ( With juanchopanzas comment )

If the size is known at compile time, you can use templates:

template < int SIZE >
class runningAverage
{
    float array [ SIZE ];
};

runningAverage < 10 > ra;

Or use classes like std::array instead of std::vector.

4 Comments

Is there an advantage to using this method over Jason's? I don't have any experience with templates....
@user3912409 There are advantages and disadvantages and the topic is discussed in many other places and a bit much to go into here.
In some situations jasons answer is more fit, in some situations mine. The only advantage independend of what your needs are, is that my method doesn't require you to deal with copy/assignment operators. However that problem is also solved for you if you just use std::vector. All the other (dis)advantages of each method depends on what you are actually using this code for, so I can't answer that right here.
Oh yea and I forgot: A disadvantage of my code is like I said in my answer, you need to know the size at compile time.
1
  1. Your member should be a pointer so that dynamic memory allocation can happen when object is constructed: float *array;.
  2. In constructor, use array = new float[a];
  3. In constructor, initialize preferably using memset rather than a loop.
  4. Have a destructor to release the memory with this line: delete[] array;
  5. To get it to compile, you need this line: #include <new>
  6. To link, don't forget to include linker flag -lstdc++ when using g++.

Since you appear to be a beginner, take a look at this useful reference for you study: http://www.cplusplus.com/doc/tutorial/dynamic/

6 Comments

I have often seen compilers reduce a loop like that and memset to the same thing.
@JasonC Ant the idiomatic way to zero initialize the array would be neither the loop nor memset, but array = new float[a]();
That's good. I have not written in C++ for years. Good to refresh.
Also you don't need to include <new> (unless you want to use std::bad_alloc and std::nothrow) for this and g++ implicitly links to libstdc++.
That source you gave helped me a lot. Much appreciated.
|

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.