Skip to main content
GameDev.net gamedev.net
🔒 Locked

pointer and new

Started by luasitdown Jan 22, 2006 at 3:40 AM 2 replies 600+ views
Original Post
luasitdown
luasitdown
class A{} class B :public A{} A* a = new B[5]; for (int i=0;i<5;i++) a.addData(); Is it right? it seem crash on my computer.
ToohrVyk
ToohrVyk
It won't work. You need a terminating semicolon after the class definitions, and a definition of the addData method.

EDIT: wow, I didn't even notice that. I must be completely stupid.

[Edited by - ToohrVyk on January 22, 2006 4:45:37 AM]
Enigma
Enigma
You cannot treat arrays polymorphically. A pointer to A cannot be treated as a pointer to the first element in an array of Bs. If you want this behaviour you should be using a pointer-to-pointer:
A * * a = new B *[5];for (int i = 0; i < 5; ++i){	a = new B();	a->addData();}

Or better yet use a container like std::vector with a smart pointer or boost::ptr_vector.

The problem occurs because array indexing is based off of the static type of the variable, not the dynamic type. So when you do a where a is of type A * the compiler translates this the same as *(a + (i * sizeof(A))), whereas an array of B objects has its ith member at *(a + (i * sizeof(B))). An extra level of indirection solves the problem because sizeof(A *) is always the same as sizeof(B *) (providing both are pointer-to-objects).

Enigma
grelle
grelle
No, it won't work. Think about how that array is laid out in memory.
class A{public:    virtual addData() {}};class B : public A{public:    B() { a = 1; }    virtual addData() {a*=2;}private:    int a;};A* a = (A*)new B[5];
This is the memory layout that the compiler assumes your array has
 0 [vtable-ptr] 1st A 4 [vtable-ptr] 2nd A 8 [vtable-ptr] 3rd A12 [vtable-ptr] 4th A16 [vtable-ptr] 5th A
This is the actual memory layout of the allocated array, provided the classes I wrote above.
 0 [vtable-ptr, int] 1st B 8 [vtable-ptr, int] 2nd B16 [vtable-ptr, int] 3rd B24 [vtable-ptr, int] 4th B32 [vtable-ptr, int] 5th B
As you can see, they don't match, because sizeof(B) is larger than sizeof(A).

You want to have an array of pointers instead.
A **a = new B*[5];for (int i=0;i<5;i++)   a = new B;for (int i=0;i<5;i++)a->addData();
Now the array is
 0 [ptr] 1st ptr to A 4 [ptr] 2nd ptr to A 8 [ptr] 3rd ptr to A12 [ptr] 4th ptr to A16 [ptr] 5th ptr to A
And each ptr in the array could point to an instance of any type that inherits from A

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.