cout << (sizeof feature / sizeof *feature) << endl;
Should be
cout << (sizeof(feature) / sizeof(*feature)) << endl;
Note the brackets. Sadly it cannot tell you what you want for a couple of reasons.
feature
is a pointer.
A pointer is a location in storage, an address, and all addresses on any system you're likely to encounter system will be the same size and probably 4 or 8 bytes. Let's assume 4 for now and sub it into the equation.
cout << (4 / sizeof(*feature)) << endl;
This will certainly print 0 because *feature
is definitely larger than 4 and in integer math 4 / <anything greater than 4>
will be truncated to 0.
If feature
was defined
Features feature[100];
And unless the size of the data block being pointed to is required to change there is no reason why it shouldn't be. Anyway, now feature is more than just a pointer to some arbitrary block of memory. It is a block of exactly 100 Features
. It has size of 100 * sizeof(feature[0]). This is a fundamental difference between an array and a pointer, so next time someone tells you "Arrays are pointers!" you can tell them to go expletive deleted themselves.
For example:
cout << (sizeof(feature) / sizeof(feature[0])) << endl;
will print 100, not the 0 we got back when feature
was a pointer. 0 != 100. Array is not pointer. Array can be used like pointer in a lot of circumstances.
Feature feature2d[100][100];
Feature ** feature2dptr = feature2d;
is not one of them. Remember this when you have to pass a 2D array into a function.
- An array knows its size but nothing about how much is being used.
From the size we can compute capacity as we did above, but to be frank this is a sucker bet. feature
could be defined
constexpr int MAX_FEATURES = 100;
Features feature[MAX_FEATURES];
And then rather than this:
cout << (sizeof(feature) / sizeof(feature[0])) << endl;
we print the much less convoluted
cout << MAX_FEATURES << endl;
But this is still not what we want.
So how do we do this right?
The preferred C++ solution is to use std::vector
. vector
does all sorts of cool things for you like resize itself and keep a count on how much of it is actually used. Plus it is Rule of Three compliant unlike the typical pointer-and-dynamic-array approach. What is The Rule of Three? Well it's really important. I recommend reading the link.
To define a vector
of Features
std::vector<Features> feature;
To store a Feature
Feature temp;
feature.push_back(temp);
Often a better route is to define a constructor for Feature
and
feature.emplace_back(feature1, feature2, feature3, feature4, feature5);
because this eliminates the need to create and copy a temporary Feature
.
To get the number of Features
in feature
feature.size();
Simple, huh?
OK. So some folk think you shouldn't use vector
until you're older and more experienced. They want you to suffer through the pit falls of memory management while you are still learning to write a decent, well-structured program and figuring out how to debug the trivial mistakes that new programmers make. I'm not down with this, but it seems to be the educational paradigm that rules the land.
Let's start with the fixed array because it is simple and much less complicated.
constexpr int MAX_FEATURES = 100;
Features feature[MAX_FEATURES];
int num_features = 0;
Every time you need to add a Feature
to the array, you first make sure you have room.
if(num_features < MAX_FEATURES)
Then add the Feature
feature[num_features] = new_feature;
and then increment, add one to, num_features
.
num_features++;
How many Features
do you have?
cout << num_features << endl;
If you absolutely must do this with pointers
int capacity = 100;
Features * feature = new Feature[capacity];
int num_features = 0;
Now you have to maintain capacity
and num_features
because the only reason you would do something this stupid is to be able to resize the memory block feature
points to as required.
if(num_features >= MAX_FEATURES)
{
Make a bigger feature
capacity = capacity * 1.5; // why 1.5? Because I felt like it.
Features * bigger_feature = new Features[capacity];
Copy everything from feature
to bigger_feature
for (int index = 0; index < num_features; index++
{
bigger_feature[index] = feature[index];
}
Free the memory used by feature
delete[] feature;
Replace feature
with bigger_feature
feature = bigger_feature;
}
Now you can
feature[num_features] = new_feature;
num_features++;
Here's that blob again in a nice cut-and-pastable blob:
if(num_features == MAX_FEATURES)
{
capacity = capacity * 1.5; // why 1.5? Because I felt like it.
Features * bigger_feature = new Features[capacity];
for (int index = 0; index < num_features; index++
{
bigger_feature[index] = feature[index];
}
delete[] feature;
feature = bigger_feature;
}
feature[num_features] = new_feature;
num_features++;
Blah. And this pointer mishmash is most definitely not Rule of Three compliant so you likely have to write copy and move constructors, assignment and move operators, and a destructor.
At the end when you are done you must
delete[] feature;
How many Features
do you have?
cout << num_features << endl;