PUSH an array C++? - c++

How would I dynamically add a value (push) to an array? I could do this in AS3, but I can't find a function for it in C++.

You can't if it's a statically defined array like so:
int array[10];
Its size is fixed. However, if you use a container such as std::vector you'd use:
std::vector::push_back()

It is not possible to 'push' in a statically allocated classic C-style array and it would not be a good idea to implement your own 'method' to dynamically reallocate an array, this has been done for you in the STL, you can use vector:
#include <vector>
// ...
std::vector<int> vect;
vect.push_back(1);
vect.size(); // --> 1
vect.push_back(2);
vect.size(); // --> 2
// ...

Use a std::vector. You cannot push into a C style array e.g. int[].

Assuming you don't mean a std::vector<>, where you obviously would use std::vector<>::push_back(), but an actual array, then you need to know
Is there at least one unused slot at the end of the array?
Yes? then put the value at the first unused slot. No? Allocate memory for a new array that is at least the size of the previous plus any amount of additional slots that you want, copy the old values over there and add the new value.
The above of course implies that you know where in the available memory the last used slot resides.
This is what std::vector<> is for, you know.

Related

Pointer to an array get size C++

int * a;
a = new int[10];
cout << sizeof(a)/sizeof(int);
if i would use a normal array the answer would be 10,
alas, the lucky number printed was 1, because sizeof(int) is 4 and iszeof(*int) is 4 too. How do i owercome this? In my case keeping size in memory is a complicated option. How do i get size using code?
My best guess would be to iterate through an array and search for it's end, and the end is 0, right? Any suggestions?
--edit
well, what i fear about vectors is that it will reallocate while pushing back, well you got the point, i can jus allocate the memory. Hoever i cant change the stucture, the whole code is releevant. Thanks for the answers, i see there's no way around, so ill just look for a way to store the size in memory.
what i asked whas not what kind of structure to use.
Simple.
Use std::vector<int> Or std::array<int, N> (where N is a compile-time constant).
If you know the size of your array at compile time, and it doens't need to grow at runtime, then use std::array. Else use std::vector.
These are called sequence-container classes which define a member function called size() which returns the number of elements in the container. You can use that whenever you need to know the size. :-)
Read the documentation:
std::array with example
std::vector with example
When you use std::vector, you should consider using reserve() if you've some vague idea of the number of elements the container is going to hold. That will give you performance benefit.
If you worry about performance of std::vector vs raw-arrays, then read the accepted answer here:
Is std::vector so much slower than plain arrays?
It explains why the code in the question is slow, which has nothing to do with std::vector itself, rather its incorrect usage.
If you cannot use either of them, and are forced to use int*, then I would suggest these two alternatives. Choose whatever suits your need.
struct array
{
int *elements; //elements
size_t size; //number of elements
};
That is self-explanatory.
The second one is this: allocate memory for one more element and store the size in the first element as:
int N = howManyElements();
int *array = int new[N+1]; //allocate memory for size storage also!
array[0] = N; //store N in the first element!
//your code : iterate i=1 to i<=N
//must delete it once done
delete []array;
sizeof(a) is going to be the size of the pointer, not the size of the allocated array.
There is no way to get the size of the array after you've allocated it. The sizeof operator has to be able to be evaluated at compile time.
How would the compiler know how big the array was in this function?
void foo(int size)
{
int * a;
a = new int[size];
cout << sizeof(a)/sizeof(int);
delete[] a;
}
It couldn't. So it's not possible for the sizeof operator to return the size of an allocated array. And, in fact, there is no reliable way to get the size of an array you've allocated with new. Let me repeat this there is no reliable way to get the size of an array you've allocated with new. You have to store the size someplace.
Luckily, this problem has already been solved for you, and it's guaranteed to be there in any implementation of C++. If you want a nice array that stores the size along with the array, use ::std::vector. Particularly if you're using new to allocate your array.
#include <vector>
void foo(int size)
{
::std::vector<int> a(size);
cout << a.size();
}
There you go. Notice how you no longer have to remember to delete it. As a further note, using ::std::vector in this way has no performance penalty over using new in the way you were using it.
If you are unable to use std::vector and std::array as you have stated, than your only remaning option is to keep track of the size of the array yourself.
I still suspect that your reasons for avoiding std::vector are misguided. Even for performance monitoring software, intelligent uses of vector are reasonable. If you are concerned about resizing you can preallocate the vector to be reasonably large.

counting elements stored in an array

I really need some help... I detail my problem, I need an array of a certain type, but I don't know its length before having retrieving values from other arrays, using for structures. In fact, I don't want to spend time passing again the several loops, and i wonder the best way to do this. Should I use a stack and a counter, and after filling it, instanciate and fill the array ?
RelAttr *tab;
//need to initialize it but how
/*several for loops retrieving values*/
tab[i] = value;
/*end for loops*/
Obviously this code is incomplete, but it is how stuff is done. And i know i can't do the affectation without having specified the array length before...
Thanks for your help
Just use a std::vector.
std::vector<RelAttr> vec;
vec.push_back(a);
vec.push_back(b);
...
It manages its own growth transparently. Every time it grows, all the items are copied, but the amortized cost of this is O(1).
The storage is also guaranteed to be contiguous, so if you really need a raw C-style array, then you can simply do this:
const RelAttr *p = &vec[0];
However, you should really only do this if you have a legacy C API that you need to satisfy.
As this is C++, suggest using a std::vector (std::vector<RelAttr>) as the number of objects is not required to be known beforehand. You can use std::vector::push_back() to add new elements as required.
The easiest way (assuming nothing exceptionally performance critical) is to use a std::vector to assemble the values and (if needed) convert the vertor to an array. Something like;
std::vector<RelAttr> vec;
...
vec.push_back(value);
...
and if you want to convert it to an array afterwards;
RelAttr *tab = new RelAttr[vec.size()];
copy( vec.begin(), vec.end(), a);
If you don't know length at compiling time you can use
function malloc, operator new, vector or another type of container

How to store an unknown number of elements in an array C++

Sorry if the title is not clear but I ll explain now my problem. I am new in C++.
I have created a class in C++. Instances of that class are the input of the program and they have to be stored in an array to perform the calculations. The problem is that the number of instances of that class that have to be defined by the user is fixed for a single run but can vary from run to run. Here an example:
#include <<blablah>blahblah>
int main()
{
int number_of_instances = 3;
MyClass first_instance(one_parameter_1, another_parameter_1);
MyClass second_instance(one_parameter_2, another_parameter_2);
MyClass third_instance(one_parameter_3, another_parameter_3);
///////////////////
NOW I HAVE TO STORE ALL THREE IN AN ARRAY LIKE
MyClass array[number_of_instances] = {first_instance, second_instance, third_instance};
THE PROBLEM IS THAT I DO NOT KNOW BEFORE HAND HOW MANY OF THEM ARE THE USER IS GOING TO INPUT
///////////////////
performCalculations(array);
return 0;
}
Thanks a lot in advance.
The typical C++ solution is to use a vector.
vector<MyClass> v;
v.push_back(first_instance); //add an already instantiated object to the end of the vector
v.push_back(second_instance);
v.push_back(third_instance);
You won't have to worry about memory management and you are able to access the vector like you would a normal array:
v[0].classMember
You can also add items to the vector in a loop if needed like so:
for(int i = 0; i < 5; i++){
v.push_back( MyClass(i, param2) );
}
And all the objects will be destructed when the vector goes out of scope if you're storing the objects directly in the vector.
One of the downsides to storing the objects directly in the vector is passing the vector as a parameter to a function. This will be a slow operation since the vector (and all the objects it holds) will have to be copied.
If you know the number of instances before you read them all in then you can allocate an array on the heap using new[]. (Don't forget to delete[] them when you've finished.) Note that this requires that the object have a default constructor.
you should use std::vector in this case rather than a built-in array.
#include <vector>
...
std::vector<MyClass> v = {first_instance, second_instance, third_instance};
...
v.push_back(fourth_instance);
If you don't know how many elements the array will contain, I would use a std::vector instead of a plain array as the vector will grow to accommodate the additional elements.
What you want is the Vector class from the standard template library, it behaves like an array but it will re-size itself if you fill it's internal allocation. If you do not need random access to it (i.e. use the [] opperator) you may want to use the List class instead. If you use List you will need to create an enumerator to step through it.
use std::vector<MyClass>, vector template can be found in <vector> header. YOu must learn a little bit to code well, before coding use any of online available c++ FAQs

Convert std::vector to array

I have a library which expects a array and fills it. I would like to use a std::vector instead of using an array. So instead of
int array[256];
object->getArray(array);
I would like to do:
std::vector<int> array;
object->getArray(array);
But I can't find a way to do it. Is there any chance to use std::vector for this?
Thanks for reading!
EDIT:
I want to place an update to this problem:
I was playing around with C++11 and found a better approach. The new solution is to use the function std::vector.data() to get the pointer to the first element.
So we can do the following:
std::vector<int> theVec;
object->getArray(theVec.data()); //theVec.data() will pass the pointer to the first element
If we want to use a vector with a fixed amount of elements we better use the new datatype std::array instead (btw, for this reason the variable name "array", which was used in the question above should not be used anymore!!).
std::array<int, 10> arr; //an array of 10 integer elements
arr.assign(1); //set value '1' for every element
object->getArray(arr.data());
Both code variants will work properly in Visual C++ 2010. Remember: this is C++11 Code so you will need a compiler which supports the features!
The answer below is still valid if you do not use C++11!
Yes:
std::vector<int> array(256); // resize the buffer to 256 ints
object->getArray(&array[0]); // pass address of that buffer
Elements in a vector are guaranteed to be contiguous, like an array.

C++ Array of Objects

I have an array in a class that should hold some instances of other objects. The header file looks like this:
class Document {
private:
long arraysize;
long count;
Row* rows;
public:
Document();
~Document();
}
Then in the constructor I initialize the array like this:
this->rows = new Row[arraysize];
But for some reason this just sets rows to an instance of Row rather than an array of rows. How would I initialize an array of Row objects?
Both SharpTooth and Wok's answers are correct.
I would add that if you are already struggling at this level you may be better off using a std::vector instead of a built-in array in this case. The vector will handle growing and shrinking transparently.
This should work. One possible "error" would be an incorrect value for arraySize.
However you should better use a std::vector from the standard library for that purpose.
#include <vector>
class Document {
// ...
std::vector<Row> rows;
// ...
};
and in your constructor:
Document::Document() : rows(arraySize) { // ... }
or
Document::Document() { rows.assign(arraySize, Row()); }
If arraySize contains a reasonable value at that point you actually get an array. I guess you trust your debugger and the debugger only shows the 0th element (that's how debuggers treat pointers), so you think there's only one object behind that pointer.
For i in [0;arraysize[, *(this->rows+i) should be an instance of row.
What precisely makes you think that rows is only one element? Make certain that you arraysize isn't 1. If it is, you'll get an array of 1 element. Mind you, you must still call delete [] with an array of size 1.
Also, why is arraysize different than count? Using that terminology, you should be making an array of count elements and arraysize should be equal to sizeof(Row) * count.
Also, you specifically ask "How would I initialize an array of Row objects?". Do you mean allocate? If so, that's how you would do so. If you mean initialize, the default constructor of Row will be called on each element of the array when the array is allocated.