If you are using c++ then you shouldn't reinvent the wheel, just use vectors:
#include <vector>
std::vector< std::vector< Stock > > StockVector;
// do this as many times as you wish
StockVector.push_back( std::vector< Stock >() );
// Now you are adding a stock to the i-th stockarray
StockVector[i].push_back( Stock() );
Edit:
I didn't understand your question, if you just want to have and array of arrays allocated on the heap just use:
Stock** StockArrayArray = new Stock*[n]; // where n is number of arrays to create
for( int i = 0; i < n; ++i )
{
StockArrayArray[i] = new Stock[25];
}
// for freeing
for( int i = 0; i < n; ++i )
{
delete[] StockArrayArray[i];
}
delete[] StockArrayArray;
Answer from akaltar on Stack OverflowIf you are using c++ then you shouldn't reinvent the wheel, just use vectors:
#include <vector>
std::vector< std::vector< Stock > > StockVector;
// do this as many times as you wish
StockVector.push_back( std::vector< Stock >() );
// Now you are adding a stock to the i-th stockarray
StockVector[i].push_back( Stock() );
Edit:
I didn't understand your question, if you just want to have and array of arrays allocated on the heap just use:
Stock** StockArrayArray = new Stock*[n]; // where n is number of arrays to create
for( int i = 0; i < n; ++i )
{
StockArrayArray[i] = new Stock[25];
}
// for freeing
for( int i = 0; i < n; ++i )
{
delete[] StockArrayArray[i];
}
delete[] StockArrayArray;
The type of a variable to a dynamic array is a pointer to the first object of the array. You want an array of dynamically allocated Stock objects, so an array of pointers to Stock, so your variable is a pointer to a pointer to Stock:
int n = 4; // dynamic size of the array;
Stock** stockArray = new Stock*[n];
for (int i = 0; i != n; ++i)
{
stockArray[i] = new Stock();
}
and freeing it:
for (int i = 0; i != n; ++i)
{
delete stockArray[i];
}
delete[] stockArray;
Dynamic array of objects in C++ - Stack Overflow
A dynamic array objects in a class - C++ Forum
Declaration of a Dynamic Array of Objects
The best/easiest way to do generic dynamic arrays in C
Videos
The functionality you look for already exits in the stl collection classes and and with out knowing you application it would be had to tell you weather you needed a pointer or not.
The basic layout of you underlying container could be something like this.
class Album{
public:
void addPhoto(Photo p){
Photos.push_back(p);
}
private:
std::vector<Photo> Photos;
};
You should use an std::vector.
I recently came across libcello which enables alot of magical stuff ontop of C by utilizing what they call "Fat Pointers" which are essentially pointers with additional information concerning the data it points to, what caught my attention was when the author described an example of how to implement arrays using this approach, so I decided to try out a very simple example and its actually very elegant and easy
The way you do it is basically have a generic header structure with additional data you want to preserve
typedef struct ptr_header{
size_t len;
size_t cap;
}ptr_header;when you want to create a new dynamic array you just allocate extra memory for the header
int *arr = NULL; // allocate 10 elements + space for the header arr = malloc(sizeof(ptr_header) + sizeof(*ar) * 10); // skip the header and make arr point to the actual data arr = (void *)((char *)arr + sizeof(ptr_header)); // access the length by going back and cast as header ((ptr_header *)arr-1)->len = 0; // access the capacity the same way ((ptr_header *)arr-1)->cap = 10;
now you can get the length and capacity by very simple arithmetic and you can do your reallocations and all the nice stuff you want to do and get creative with some macro magic
The best thing about it is you dont have to create a struct for every dynamic array of the type and that subscripting works -which I didnt even think of when I implemented it- and everything works
here is a simple full example to get the point across
For building containers you obviously want to use one of the standard containers (such as a std::vector). But this is a perfect example of the things you need to consider when your object contains RAW pointers.
If your object has a RAW pointer then you need to remember the rule of 3 (now the rule of 5 in C++11).
- Constructor
- Destructor
- Copy Constructor
- Assignment Operator
- Move Constructor (C++11)
- Move Assignment (C++11)
This is because if not defined the compiler will generate its own version of these methods (see below). The compiler generated versions are not always useful when dealing with RAW pointers.
The copy constructor is the hard one to get correct (it's non trivial if you want to provide the strong exception guarantee). The Assignment operator can be defined in terms of the Copy Constructor as you can use the copy and swap idiom internally.
See below for full details on the absolute minimum for a class containing a pointer to an array of integers.
Knowing that it is non trivial to get it correct you should consider using std::vector rather than a pointer to an array of integers. The vector is easy to use (and expand) and covers all the problems associated with exceptions. Compare the following class with the definition of A below.
class A
{
std::vector<int> mArray;
public:
A(){}
A(size_t s) :mArray(s) {}
};
Looking at your problem:
A* arrayOfAs = new A[5];
for (int i = 0; i < 5; ++i)
{
// As you surmised the problem is on this line.
arrayOfAs[i] = A(3);
// What is happening:
// 1) A(3) Build your A object (fine)
// 2) A::operator=(A const&) is called to assign the value
// onto the result of the array access. Because you did
// not define this operator the compiler generated one is
// used.
}
The compiler generated assignment operator is fine for nearly all situations, but when RAW pointers are in play you need to pay attention. In your case it is causing a problem because of the shallow copy problem. You have ended up with two objects that contain pointers to the same piece of memory. When the A(3) goes out of scope at the end of the loop it calls delete [] on its pointer. Thus the other object (in the array) now contains a pointer to memory that has been returned to the system.
The compiler generated copy constructor; copies each member variable by using that members copy constructor. For pointers this just means the pointer value is copied from the source object to the destination object (hence shallow copy).
The compiler generated assignment operator; copies each member variable by using that members assignment operator. For pointers this just means the pointer value is copied from the source object to the destination object (hence shallow copy).
So the minimum for a class that contains a pointer:
class A
{
size_t mSize;
int* mArray;
public:
// Simple constructor/destructor are obvious.
A(size_t s = 0) {mSize=s;mArray = new int[mSize];}
~A() {delete [] mArray;}
// Copy constructor needs more work
A(A const& copy)
{
mSize = copy.mSize;
mArray = new int[copy.mSize];
// Don't need to worry about copying integers.
// But if the object has a copy constructor then
// it would also need to worry about throws from the copy constructor.
std::copy(©.mArray[0],©.mArray[c.mSize],mArray);
}
// Define assignment operator in terms of the copy constructor
// Modified: There is a slight twist to the copy swap idiom, that you can
// Remove the manual copy made by passing the rhs by value thus
// providing an implicit copy generated by the compiler.
A& operator=(A rhs) // Pass by value (thus generating a copy)
{
rhs.swap(*this); // Now swap data with the copy.
// The rhs parameter will delete the array when it
// goes out of scope at the end of the function
return *this;
}
void swap(A& s) noexcept
{
using std::swap;
swap(this.mArray,s.mArray);
swap(this.mSize ,s.mSize);
}
// C++11
A(A&& src) noexcept
: mSize(0)
, mArray(NULL)
{
src.swap(*this);
}
A& operator=(A&& src) noexcept
{
src.swap(*this); // You are moving the state of the src object
// into this one. The state of the src object
// after the move must be valid but indeterminate.
//
// The easiest way to do this is to swap the states
// of the two objects.
//
// Note: Doing any operation on src after a move
// is risky (apart from destroy) until you put it
// into a specific state. Your object should have
// appropriate methods for this.
//
// Example: Assignment (operator = should work).
// std::vector() has clear() which sets
// a specific state without needing to
// know the current state.
return *this;
}
}
I'd recommend using std::vector: something like
typedef std::vector<int> A;
typedef std::vector<A> AS;
There's nothing wrong with the slight overkill of STL, and you'll be able to spend more time implementing the specific features of your app instead of reinventing the bicycle.