-->

Array memory Allocation doesn't work

2019-07-31 07:29发布

问题:

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!

回答1:

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());
}


回答2:

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

new A*[array_size]



回答3:

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.