How do I initialize this variable-size struct? - c++

How do I initialize the variable-size C++ struct "StructB" that is declared below:
#include <iostream>
#include <string>
typedef struct {
char* a;
int b;
} StructA;
typedef struct {
StructA* pointers[];
int pcount;
int numbers[];
int ncount;
} StructB;
int main()
{
StructB *sb = new StructB; // I need 'sb' to be allocated in the heap
sb->pcount = 5;
sb->ncount = 3;
sb->pointers = new StructA*[sb->pcount];
sb->numbers = int[sb->ncount];
}
I got these compiler errors. What do these error means and how do I fix them? THank you.
In function 'int main()':
21:43: error: incompatible types in assignment of 'StructA**' to 'StructA* [0]'
22:19: error: expected primary-expression before 'int'
22:19: error: expected ';' before 'int'

listen this is not the good c++ way, you are doing C in a C++ environment
which is OK if it gives you some advantage (IO, typechecking, etc.) or for learning.
Dynamic allocation of memory in C style is entirely manual. So is deallocation.
Since you are using typedef, typedef can make things clearer for you and for the compiler.
Here is a tortured example which I think does what you want.
Notice that it is done "The Hard Way" which is actually the easy way in this case of
C style coding in C++;
#include <iostream>
#include <string>
typedef struct {
char* a;
int b;
} StructA;
typedef StructA* A_p; // A_p is "pointer to structA" (contains address of struct)
typedef A_p* A_p_Array; // A_p_Array is "pointer to A_p" (aka StructA**) contains address of A_p
typedef int* int_Array; // int_Array is "pointer to int" contains address of integer
typedef struct {
A_p_Array A_pointers;
int pcount;
int_Array numbers;
int ncount;
} StructB;
int main()
{
int i;
StructA *sa = new StructA;
StructB *sb = new StructB;
sb->pcount = 5;
sb->ncount = 3;
A_p_Array tmp_A_array;
A_p tmp;
for ( i = 0 ; i < sb->pcount; i++)
{
tmp_A_array = new A_p; // create a StructA pointer
tmp = new StructA; // create a StructA
tmp_A_array = &tmp; // put address of tmp in mp_A_array
tmp_A_array++; // increment array address
}
sb->A_pointers = tmp_A_array; // A_pointers now contains address of dynamically created array
tmp_A_array = NULL; // clear pointer but do NOT delete!
int_Array tmp_i_array;
for ( i = 0 ; i < sb->ncount; i++)
{
tmp_i_array = new int(0); // c++ can create ints with initial values
tmp_i_array++;
}
sb->numbers = tmp_i_array;
tmp_i_array = NULL; // clear pointer but do NOT delete!
/****** USE Structs A & B *****/
// clean up the heap
A_p Ap;
for ( i = 0 ; i < sb->pcount; i++)
{
Ap = sb->A_pointers[i];
delete Ap; // each struct released separately
}
int* ip;
for ( i = 0 ; i < sb->ncount; i++)
{
ip = & sb->numbers[i];
delete ip; //each int released separately
}
delete sb;
return 0;
} // main
There are better ways to do the above
which is one reason c++ and higher languages were invented.
When you get to classes it will be somewhat easier
but you can run in to the same types of problems there
so getting pointers and pointers-to-pointers down
now will serve you in good stead later.

Related

Realloc pointer in C++ that was malloced() in C

I'm writing a library in C++ that is supposed to interop with other C code/libraries.
If a client passes an array that was malloc()'d in C into a library function, can the C++ function safely call realloc() on that memory block and return it (leaving it up to the C caller to free() it?
Or does C++ use a different implementation and bookkeeping than C and they are incompatible.
Here's some example code:
C code:
c_header.h:
struct my_list {
int count;
int capacity;
long* array;
};
c_code.c:
#include "c_header.h"
#include "ccp_header.h"
int some_method() {
struct my_list list1;
list1.count = 0;
list1.array = malloc(sizeof(long)*5);
list1.capacity = 5;
int ret = cpp_extend_list(&list1) // todo: error checking etc...
free(list1.array);
}
C++ code:
#include "c_header.h"
int cpp_extend_list(struct my_list *list) {
long* temp = realloc(list->array, sizeof(long) * (list->capacity + 10));
if (!temp) return -1;
list->array = temp;
list->capacity+=10;
return 0;
}

How to dynamically allocate arrays in C++

I know how to dynamically allocate space for an array in C. It can be done as follows:
L = (int*)malloc(mid*sizeof(int));
and the memory can be released by:
free(L);
How do I achieve the equivalent in C++?
Specifically, how do I use the new and delete[] keywords? Especially in the context of creating/destroying a linked list node, or creating and destroying an array whose size is given by a variable during compile time?
int* L = new int[mid];
delete[] L;
for arrays (which is what you want) or
int* L = new int;
delete L;
for single elements.
But it's more simple to use vector, or use smartpointers, then you don't have to worry about memory management.
std::vector<int> L(mid);
L.data() gives you access to the int[] array buffer and you can L.resize() the vector later.
auto L = std::make_unique<int[]>(mid);
L.get() gives you a pointer to the int[] array.
Following Info will be useful :
Source : https://www.learncpp.com/cpp-tutorial/6-9a-dynamically-allocating-arrays/
Initializing dynamically allocated arrays
If you want to initialize a dynamically allocated array to 0, the syntax is quite simple:
int *array = new int[length]();
Prior to C++11, there was no easy way to initialize a dynamic array to a non-zero value (initializer lists only worked for fixed arrays). This means you had to loop through the array and assign element values explicitly.
int *array = new int[5];
array[0] = 9;
array[1] = 7;
array[2] = 5;
array[3] = 3;
array[4] = 1;
Super annoying!
However, starting with C++11, it’s now possible to initialize dynamic arrays using initializer lists!
int fixedArray[5] = { 9, 7, 5, 3, 1 }; // initialize a fixed array in C++03
int *array = new int[5] { 9, 7, 5, 3, 1 }; // initialize a dynamic array in C++11
Note that this syntax has no operator= between the array length and the initializer list.
For consistency, in C++11, fixed arrays can also be initialized using uniform initialization:
int fixedArray[5] { 9, 7, 5, 3, 1 }; // initialize a fixed array in C++11
char fixedArray[14] { "Hello, world!" }; // initialize a fixed array in C++11
One caveat, in C++11 you can not initialize a dynamically allocated char array from a C-style string:
char *array = new char[14] { "Hello, world!" }; // doesn't work in C++11
If you have a need to do this, dynamically allocate a std::string instead (or allocate your char array and then strcpy the string in).
Also note that dynamic arrays must be declared with an explicit length:
int fixedArray[] {1, 2, 3}; // okay: implicit array size for fixed arrays
int *dynamicArray1 = new int[] {1, 2, 3}; // not okay: implicit size for dynamic arrays
int *dynamicArray2 = new int[3] {1, 2, 3}; // okay: explicit size for dynamic arrays
you allocate memory using the new operator and release a pointer using delete operator. Note that you can't delete normal variables, only pointers and arrays can be deleted after accomplishing their task.
int * foo;
foo = new int [5];
delete[] foo;
a complete program
#include <iostream>
#include <new>
using namespace std;
int main ()
{
int i,n;
int * p;
cout << "How many numbers would you like to type? ";
cin >> i;
p= new (nothrow) int[i];
if (p == nullptr)
cout << "Error: memory could not be allocated";
else
{
for (n=0; n<i; n++)
{
cout << "Enter number: ";
cin >> p[n];
}
cout << "You have entered: ";
for (n=0; n<i; n++)
cout << p[n] << ", ";
delete[] p;
}
return 0;
}
result
How many numbers would you like to type? 5
Enter number : 75
Enter number : 436
Enter number : 1067
Enter number : 8
Enter number : 32
You have entered: 75, 436, 1067, 8, 32,
In C++ we have the methods to allocate and de-allocate dynamic memory.The variables can be allocated dynamically by using new operator as,
type_name *variable_name = new type_name;
The arrays are nothing but just the collection of contiguous memory locations, Hence, we can dynamically allocate arrays in C++ as,
type_name *array_name = new type_name[SIZE];
and you can just use delete for freeing up the dynamically allocated space, as follows,
for variables,
delete variable_name;
for arrays,
delete[] array_name;
You need to be extremely careful when using raw pointers with dynamic memory but here is a simple example.
int main() {
// Normal Pointer To Type
int* pX = nullptr;
pX = new int;
*pX = 3;
std::cout << *pX << std::endl;
// Clean Up Memory
delete pX;
pX = nullptr;
// Pointer To Array
int* pXA = nullptr;
pXA = new int[10]; // 40 Bytes on 32bit - Not Initialized All Values Have Garbage
pXA = new int[10](0); // 40 Bytes on 32bit - All Values Initialized To 0.
// Clean Up Memory To An Array Of Pointers.
delete [] pXA;
pXA = nullptr;
return 0;
} // main
To avoid memory leaks; dangling pointers, deleting memory to early etc. Try using smart pointers. They come in two varieties: shared and unique.
SomeClass.h
#ifndef SOME_CLASS_H
#define SOME_CLASS_H
class SomeClass {
private:
int m_x;
public:
SomeClass();
explicit SomeClass( x = 0 );
void setX( int x );
int getX() const;
private:
SomeClass( const SomeClass& c ); // Not Implemented - Copy Constructor
SomeClass& operator=( const SomeClass& c ); Not Implemented - Overloaded Operator=
}; // SomeClass
#endif // SOME_CLASS_H
SomeClass.cpp
#include "SomeClass.h"
// SomeClass() - Default Constructor
SomeClass::SomeClass() :
m_x( x ) {
} // SomeClass
// SomeClass() - Constructor With Default Parameter
SomeClass::SomeClass( int x ) :
m_x( x ) {
} // SomeClass
// setX()
void SomeClass::setX( int x ) {
m_x = x;
} // setX
// getX()
void SomeClass::getX() const {
return m_x;
} // getX
Old Way Of Using Dynamic Memory
#include <iostream>
#include "SomeClass.h"
int main() {
// Single Dynamic Pointer
SomeClass* pSomeClass = nullptr;
pSomeClass = new SomeClass( 5 );
std::cout << pSomeClass->getX() << std::endl;
delete pSomeClass;
pSomeClass = nullptr;
// Dynamic Array
SomeClass* pSomeClasses = nullptr;
pSomeClasses = new SomeClasses[5](); // Default Constructor Called
for ( int i = 0; i < 5; i++ ) {
pSomeClasses[i]->setX( i * 10 );
std::cout << pSomeSomeClasses[i]->getX() << std::endl;
}
delete[] pSomeClasses;
pSomeClasses = nullptr;
return 0;
} // main
The problem here is knowing when, where and why to delete memory; knowing who is responsible. If you delete the memory to manage it and the user of your code or library assumes you didn't and they delete it there is a problem since the same memory is trying to be deleted twice. If you leave it up to the user to delete it and they assumed you did and they don't you have a problem and there is a memory leak. This is where the use of smart pointers come in handy.
Smart Pointer Version
#include <iostream>
#include <memory>
#include <vector>
#include "SomeClass.h"
int main() {
// SHARED POINTERS
// Shared Pointers Are Used When Different Resources Need To Use The Same Memory Block
// There Are Different Methods To Create And Initialize Shared Pointers
auto sp1 = std::make_shared<SomeClass>( 10 );
std::shared_ptr<SomeClass> sp2( new SomeClass( 15 ) );
std::shared_ptr<SomeClass> sp3;
sp3 = std::make_shared<SomeClass>( 20 );
std::cout << "SP1: " << sp1->getX() << std::endl;
std::cout << "SP2: " << sp2->getX() << std::endl;
std::cout << "SP3: " << sp3->getX() << std::endl;
// Now If you Reach The Return Of Main; These Smart Pointers Will Decrement
// Their Reference Count & When It Reaches 0; Its Destructor Should Be
// Called Freeing All Memory. This Is Safe, But Not Guaranteed. You Can
// Release & Reset The Memory Your Self.
sp1.reset();
sp1 = nullptr;
sp2.reset();
sp2 = nullptr;
sp3.reset();
sp3 = nullptr;
// Need An Array Of Objects In Dynamic Memory?
std::vector<std::shared_ptr<SomeClass>> vSomeClasses;
vSomeClasses.push_back( std::make_shared<SomeClass>( 2 ) );
vSomeClasses.push_back( std::make_shared<SomeClass>( 4 ) );
vSomeClasses.push_back( std::make_shared<SomeClass>( 6 ) );
std::vector<std::shared_ptr<SomeClass>> vSomeClasses2;
vSomeClasses2.push_back( std::shared_ptr<SomeClass>( new SomeClass( 3 ) ) );
vSomeClasses2.push_back( std::shared_ptr<SomeClass>( new SomeClass( 5 ) ) );
vSomeClasses2.push_back( std::shared_ptr<SomeClass>( new SomeClass( 7 ) ) );
// UNIQUE POINTERS
// Unique Pointers Are Used When Only One Resource Has Sole Ownership.
// The Syntax Is The Same For Unique Pointers As For Shared Just Replace
// std::shared_ptr<SomeClass> with std::unique_ptr<SomeClass> &
// replace std::make_shared<SomeClass> with std::make_unique<SomeClass>
// As For Release Memory It Is Basically The Same
// The One Difference With Unique Is That It Has A Release Method Where Shared Does Not.
auto mp1 = std::make_unique<SomeClass>( 3 );
mp1.release();
mp1.reset();
mp1 = nullptr;
// Now You Can Also Do This:
// Create A Unique Pointer To An Array Of 5 Integers
auto p = make_unique<int[]>( 5 );
// Initialize The Array
for ( int i = 0; i < 5; i++ ) {
p[i] = i;
}
return 0;
} // main
Here Are Reference Links To Both Shared & Unique Pointers
https://msdn.microsoft.com/en-us/library/hh279669.aspx
https://msdn.microsoft.com/en-us/library/hh279676.aspx

A pointer to an array of pointers

I know I should know this, but it's late and my brain just won't put the pieces together.
This is as straight forward as a question can get:
I have a struct item. I want to create a pointer to an array of pointers to that item type.
Eg.
struct item {
int data;
string moreData;
};
I want to have an ArrayPointer that point's to an array. I want that array to contain in each element a pointer to an item.
How do I do this in C++, or more sepcifically where do I need to put how many dereferencing operators? I know how to declare basic (single indirection) pointers and am pretty fluent in their use.
I need information for the following steps if at all possible:
Declaring the ArrayPointer.
Initializing the ArrayPointer with a size s.
Initializing each element of ArrayPointer with new item.
eg:
for(int i = 0; i < s; i++)
ArrayPointer[i] = // a new item
I feel like as soon as someone posts an answer I'm going to facepalm so hard I break my nose.
If I have understood correctly then you need something like this
item **ArrayPointer = new item *[s];
for ( int i = 0; i < s; i++ )
{
ArrayPointer[i] = new item; { i, "More Data" };
}
Or
item **ArrayPointer = new item *[s];
for ( int i = 0; i < s; i++ )
{
ArrayPointer[i] = new item;
ArrayPointer[i]->data = i;
ArrayPointer[i]->moreData = "More Data";
}
To free the allocated memory you can in reverse order
for ( int i = 0; i < s; i++ )
{
delete ArrayPointer[i];
}
delete [] ArrayPointer;
Otherewise if s is a constant then you may simply declare an array of pointers. For example
item * ArrayPointer[s];
for ( int i = 0; i < s; i++ )
{
ArrayPointer[i]->data = i;
ArrayPointer[i]->moreData = "More Data";
}
file.h
struct item {
int data;
string moreData;
};
item ** array;
file.cpp
array = new item*[s];
for(int i = 0; i < s; i++)
{
array[i] = new item;
array[i]->data = 10;
array[i]->moreData = "data";
}
What you want is an array of struct item *, which are pointers to item structs.
An array of such pointers is a struct item **.
#include <string>
#include <cstdlib>
using namespace std;
struct item {
int data;
string moreData;
};
struct item * newItem(int data, string moreData) {
struct item *result = (struct item *) malloc(sizeof(struct item));
result->data = data;
result->moreData = moreData;
return result;
}
struct item ** array; // We don't know the size of the array in advance.
int main() {
int arraySize = 3; // We get this value from somewhere (user input?).
array = (struct item **) malloc(3*sizeof(struct item *));
// Now the array has been allocated. There is space for
// arraySize pointers.
array[0] = newItem(5, "ant"); // Let's make some items. Note that
array[1] = newItem(90, "bear"); // newItem() returns a pointer to
array[2] = newItem(25, "cat"); // an item.
return 0;
}

A shared pointer query from a novice user. I have code below that crashes when using a container of class with member shared pointers

//this is my main Method ,this was an experiment to understand shared pointer usage
#include <iostream>
#include "shared_ptrtestA.h"
int main(int argc, const char * argv[]) {
// declare a shared pointer to the class
sharedptr_testA* A = new sharedptr_testA(5);
//class has a vector , push back a new instance into the vector
A->mvect.push_back(sharedptr_testA::Aptr(new sharedptr_testA::testA(
sharedptr_testA::sharedptr_testB::Create(1) , sharedptr_testA::sharedptr_testC::Create(1)
)));
//class has a vector , push back a new instance into the vector
A->mvect.push_back(sharedptr_testA::Aptr(new sharedptr_testA::testA(
sharedptr_testA::sharedptr_testB::Create(2),sharedptr_testA::sharedptr_testC::Create(2)
)));
//iterate the vector populated above
for(std::vector<sharedptr_testA::Aptr>::iterator it = A->mvect.begin() ;
it!= A->mvect.end() ; it++)
{
// get members from the vector iterator
sharedptr_testA:: sharedptr_testB::Bptr B = (*it)->mb;
sharedptr_testA:: sharedptr_testC::Cptr C = (*it)->mc;
// print contents of members
for(int i = 0 ; i < B->m_size ; i++)
{
std::cout<<B->bytes[i]<<'\t';
}
std::cout <<std::endl;
for(int i = 0 ; i < C->m_size ; i++)
{
std::cout<<C->bytes[i]<<'\t';
}
std::cout <<std::endl;
}
}
//this was the main method above and the expected output was
B
C
BB
CC
The structure of the classes used are
//Header File
#ifndef shared_ptrtest_shared_ptrtestA_h
#define shared_ptrtest_shared_ptrtestA_h
#include <memory>
#include <functional>
#include <vector>
class sharedptr_testA
{
public:
// constructor and destructor
sharedptr_testA(int vsize);
~sharedptr_testA();
// an internal class member defined
class sharedptr_testB
{
public:
typedef std::shared_ptr<sharedptr_testB> Bptr;
//static create method
static Bptr Create(int msize)
{
return Bptr(new sharedptr_testB(msize));
}
//members
int m_size;
char *bytes;
//private contructor
private:
sharedptr_testB(int size)
{
m_size = size;
bytes = new char[size];
for(int i = 0 ; i < size ; i++)
bytes[size]= 'B';
}
};
//class c has same structure as class B above
class sharedptr_testC
{
public:
typedef std::shared_ptr<sharedptr_testC> Cptr;
static Cptr Create(int msize)
{
return Cptr(new sharedptr_testC(msize));
}
int m_size;
char *bytes;
private:
sharedptr_testC(int size)
{
m_size = size;
bytes = new char[size];
for(int i = 0 ; i < size ; i++)
bytes[size]= 'C';
}
};
// struct containing shared pointers to classes defined above
struct testA
{
testA(sharedptr_testB::Bptr B, sharedptr_testC::Cptr C)
{
mb = B;
mc = C;
}
sharedptr_testB::Bptr mb;
sharedptr_testC::Cptr mc;
};
typedef std::shared_ptr<testA> Aptr;
std::vector<Aptr> mvect;
};
#endif
//The short cpp file for the above class contains only constructor and destructor
#include "shared_ptrtestA.h"
sharedptr_testA::sharedptr_testA(int vsize)
:mvect(vsize)
{
}
sharedptr_testA::~sharedptr_testA()
{
}
What is wrong in the above code ? I wrote this to understand shared pointer usage
You have two bugs in your program:
The loops in constructors of sharedptr_testB and sharedptr_testC use size instead of i for indexing. It should be:
sharedptr_testB(int size)
{
m_size = size;
bytes = new char[size];
for(int i = 0 ; i < size ; i++)
bytes[i]= 'B';
}
(DTTO) for sharedptr_testC)
You start with a vector of size 5, which means it stores five null pointers. Then you append two elements to it (size 7, five nulls + two valid pointers). The you iterate over it, dereferencing each pointer. This of course crashes, since there are nulls at the beginning. Simply initialise the vector as empty.
sharedptr_testA* A = new sharedptr_testA(0);
With these two fixes, the code works.
Side notes 1 (C++):
The code is next to impossible to read. I strongly suggest you use a better naming scheme.
sharedptr_testB and sharedptr_testC leak memory. I understand it's just a learning excercise, I'd just like to point it out. You'd be better off with std::vector<char> in them instead of char*.
Side notes 2 (Stack Overflow):
If you have a crashing program, you should generally try to debug it yourself before asking an SO question. Stepping through the program through a debugger would easily have uncovered both the issues.

Dynamically Allocated Array of Struct Pointers in C++

Ok i'm pretty new to c++ (I think what we are learning is somehow an hybrid of c and c++).
I've found alot of anwsers to my question, sadly all of them where in C using malloc.
struct A {
int randomStuff = 0;
};
struct B {
int numOfA= 5; // In reality this number is variable.
A** arrayOfA;
};
The struct are given to us. Now I need to allocate and fill this array with pointers to, I guess, A pointers. <- Correct me here if I'm wrong pointers are still quite complex for me.
A * a1 = new A;
A * a2 = new A;
B * b = new B;
// Allocate space for the array...
b->arrayOfA = new A*[numOfA];
// Next I want to initialize the pointers to NULL
for(int i; i < b->numOfA; i++){
b->arrayOfA[i] = NULL;
}
// In another function I would the assign a value to it
b->arrayOfA[0] = a1;
b->arrayOfA[1] = a2;
The way I see it is that b->arrayOfA needs to point to an array of A struct...somehow like this
b->arrayOfA = new A*;
A * arr[numOfA];
b->arrayOfA = arr;
My brain is bleeding.
How do I correctly allocate it and assign existing values(A structs) to it?
*edit
It would appear that the code was working as intended and that my display was causing me issues. Basically, I needed an array "arrayOfA[]" in which I would put the pointers to an A struct. Effectively making the result of this:
cout << arrayOfA[0]->randomStuff // 0 would be displayed
To be 0.
You could allocate an array of pointers and for each of them allocate an array of your objects
int x = 5, y = 6;
b->arrayOfA = new A*[x]; //array of pointers
for(int i=0;i<x;i++){
b->arrayOfA[i] = new A[y]; //matrix (array of arrays)
}
for(int i=0;i<x;i++){
delete[] b->arrayOfA[i]; //don't forget to free memory
}
delete[] b->arrayOfA;
You should be able to just use a vector:
#include <vector>
int main()
{
vector<A> vector_of_a;
vector_of_a.push_back(a1); //store a1 in the vector
vector_of_a.push_back(a2); //store a2 in the vector
//...
std::cout << "Number of A's: " << vector_of_a.size() << std::endl;
std::cout << vector_of_a[0].randomStuff << std::endl; //prints 0 as specified but with '.' not '->' Objects are still on the heap, and not the stack.
}
The A's in the vector are stored on the heap, but you don't need to manage the memory yourself (no need for malloc/free or new/delete.
The A objects will be disposed of correctly when the vector goes out of scope.
You also get
You can push in pointers to objects too, but this reduces the usefulness of the vector as you then have to do your own memory management for the objects:
#include <vector>
int main()
{
A* a1 = new A();
A* a2 = new A();
vector<A> vector_of_a;
vector_of_a.push_back(a1); //store pointer to a1 in the vector
vector_of_a.push_back(a2); //store pointer to a2 in the vector
//...
std::cout << "Number of A's: " << vector_of_a.size() << std::endl;
std::cout << vector_of_a[0]->randomStuff << std::endl; //prints 0 as specified
//...
for (auto i : vector_of_a)
{
delete (i);
}
vector_of_a.clear();
}
If you really don't want to use a vector, then I reccommend turning your struct B into a fully fledged class.
It gives you the benefit of encapsulation, functions to manage the data are stored within the class, and the class does the memory management and doesn't leave it to the
user's code to manage and clear up behind it:
class B
{
public:
array_of_A(unsigned int size);
~array_of_A();
bool init_array();
unsigned int get_size();
A** get_array();
private:
unsigned int num_of_A;
A** array_of_A;
}
B::array_of_A(unsigned int size)
{
num_of_a = size;
array_of_A = new A*[size]; //create array
memset (array_of_A, nullptr, size); //initialise contents to nullptr
}
B::~B()
{
for(unsigned int i = 0; i < num_of_a; i++)
{
delete array_of_a[i]; //delete each A
}
delete[](array_of_a); //delete the array of pointers.
}
unsigned int B::get_size()
{ return num_of_A; }
A** B::get_array()
{ return array_of_A; }
int main()
{
B b((5)); //most vexing parse...
b.get_array()[0] = new A();
b.get_array()[1] = new A();
b.get_array()[2] = new A();
std::cout << b.get_array()[0]->randomStuff << std::endl //prints 0 as requested
} //b goes out of scope, destructor called, all memory cleaned up
aaaand by internalising the memory management and supporting arbitarilly long arrays, we've just started implementing a (much) simpler version of vector. But good for practice/learning.