Alon Shmiel
Alon Shmiel

Reputation: 7121

Array memory Allocation doesn't work

I have the next classes:

class A {
};

class B : public A {
  int num;
};

in my main I have:

int main() {
    A* vec; // A is a class with pure virtual functions
    vec = new B[2]; // want to create a vector of B
}

vec[0] is defined correctly, but vec[1] is NULL. why didn't it allocate me a fit memory?

I don't want to change the lines of the main. just make it working.

(I know I can change the main into: B* vec = new B[2] but I don't want)

any help appreciated!

Upvotes: 1

Views: 195

Answers (3)

Captain Obvlious
Captain Obvlious

Reputation: 20073

You cannot treat arrays polymorphically, the C++ language does not support it. The expression vec[x] uses pointer arithmetic to determine the location of the element. If you are accessing it through a base class pointer it will not work if the size of the objects vary in any way.

For example, you have base class that is 4 bytes in size and the subclass is 8 bytes in size.

base *a = new child[4];

When you access a[1] the compiler calculates the offset using the size of the base class. In this case the offset is 4 bytes which ends up pointing to the middle of the first element.

I recommend using a std::vector or std::array of pointers with an appropriate smart pointer.

// For arrays that needs to be resized (requires delete for each new)
std::vector<A*> vec(5, NULL);
for(int i = 0; i < vec.size(); i++)
{
    vec[i] = new B();
}

// for arrays that are fixed in size (requires delete for each new)
std::array<A*, 5> vec;
for(int i = 0; i < vec.size(); i++)
{
    vec[i] = new B();
}

// for arrays that are fixed in size with smart pointers
// no delete needed 
std::array<std::unique_ptr<A>, 5> vec;
for(int i = 0; i < vec.size(); i++)
{
    vec[i].reset(new B());
}

Upvotes: 5

makc
makc

Reputation: 2579

if you would like it to be polymorphic just create an array of pointers

new A*[array_size]

Upvotes: 1

MobA11y
MobA11y

Reputation: 18900

This code snippet illustrates the problem you are having.

#include <iostream>
using namespace std;
class A {
};

class B : public A {
  int num;
};

int main() {
    A* vec; // A is a class with pure virtual functions
    vec = new B[2]; // want to create a vector of B

    cout << sizeof(vec) << endl;
    cout << sizeof(*vec) << endl;
    cout << sizeof(vec[2]) << endl;
    cout << sizeof(new B()) << endl;
}

In pointer arrithmetic, the size of the type of the pointer you allocated is what is used for incrementing, not the size of the true type of the object it is pointing to. More simply, the language does not support polymorphic arrays. This is simply an explanation of why.

Upvotes: 0

Related Questions