2

My code was giving the wrong answer so I thinned it down to this. When my variable arrayCounter=0, then it returns the correct answer in the array. But when arrayCounter=1, I get the incorrect answer of 0.

#include <iostream>
using namespace std;

struct base
{
  int x,y;
};

struct myStruct : base
{
  char c;
  int numOne;
}; myStruct MS[10]; //array of myStruct

base * returnArray(char c)  //function that returns array type
{
  if(c=='m'){ return MS;}
  //I plan to have other structs here similar to myStruct.
}

int main()
{
  MS[0].x=204;   //init 0 value in array
  MS[1].x=97;    //init 1 value in array

  int arrayCounter=0; //count through array. if=0, returns correctly. If=1, then not correct...
  cout<<returnArray('m')[arrayCounter].x<<endl; //MS[1].x=204, MS[1].x=0

  system("pause");
}

4 Answers 4

1

Pointer arithmetic, including indexing into an array, is static. It does not know the dynamic type of the objects you are accessing. As such, if you use a base pointer to an array of derived objects, and you try to increment this pointer, you are going to have a problem, because the pointer arithmetic assumes the object being pointed to really is a base object.

If you really want polymorphic behaviour with arrays, you'll have to use an array of pointers, and make the returnArray function return base**.

Sign up to request clarification or add additional context in comments.

7 Comments

This sounds interesting. I tried it but it would not compile. does base ** return *MS, the pointer to myStruct?
Well, you'd have to declare MS as an array of pointers in order to use this approach
im ok with that method. so i made myStruct ()MS[10]. and base(*) but i get an error. do you know why? thank you for your help btw. i have had this problem for a while.
myStruct MS[10] isn't an array of pointers. It's just an array of myStruct objects.
"invalid conversion from myStruct**' to base**'" And 'x' has not been declared. all i did was make those two changes you suggested. weird error.
|
1

Because your function returnArray() returns array of base while operator [] actually calculates offset basing on element size smth like this:

template<typename T>
T& operator [](T* array, size_t index)
{
  *(array + sizeof(T) * index);
}

So when you pass an array of base this operator will calculate its size as sizeof(int) + sizeof(int). Polymorphysm only works with pointers. So it'll go like this myStruct* a[10] Or you can just return an array of myStruct: myStruct* returnArray();

And one more thing. If eventually you'll create a derived class that is even bigger than myStruct and try to store it in the array you'll succeed but the object you will store will be shrinked ti fit the size of myStruct and you will lose data.

Comments

1

the problem is sizeof(Base)= 8, when arrayCounter increase from 0 to 1 in returnArray('m')[arrayCounter], the address change is 8, but sizeof(myStruct) = 16, the address change 16 from MS[0] to MS[1],as the code shows

if you want this to happen, you can change the pointer type

cout<<((myStruct*)returnArray('m'))[arrayCounter].x<<endl;

the code list below outputs:

address of base* array index 0: 0x6013c0
address of base* array index 1: 0x6013c8
address of MS array index 0: 0x6013c0
address of MS array index 1: 0x6013d0
97

#include <iostream>
#include <stdio.h>
using namespace std;

struct base
{
  int x,y;
};

struct myStruct : base
{
  char c;
  int numOne;
}; myStruct MS[10]; //array of myStruct

base * returnArray(char c)  //function that returns array type
{
  if(c=='m'){ return MS;}
  //I plan to have other structs here similar to myStruct.
}

int main()
{
  MS[0].x=204;   //init 0 value in array
  MS[1].x=97;    //init 1 value in array

  int arrayCounter=1; //count through array. if=0, returns correctly. If=1, then not correct...
  printf("address of base* array index 0: %p\n",&returnArray('m')[0]);
  printf("address of base* array index 1: %p\n",&returnArray('m')[1]);

  printf("address of MS array index 0: %p\n",&MS[0]);
  printf("address of MS array index 1: %p\n",&MS[1]);
  cout<<((myStruct*)returnArray('m'))[arrayCounter].x<<endl; //MS[1].x=204, MS[1].x=0

  return 0;
}

Comments

0

myStruct* returnArray(char c) will fix your current problem. But you will still be confused if you want to use many derived class in your codes.

The following codes might be a better choice:

struct Base
{
    int x,y;
    int get_x(){
        return x;
    }
}

cout << MS[arrayCounter].get_x() << endl;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.