具有基本结构的结构数组返回错误的答案

时间:2014-02-25 01:11:25

标签: c++ arrays struct return

我的代码给出了错误的答案,所以我将其简化为此。 当我的变量arrayCounter = 0时,它返回数组中的正确答案。 但是当arrayCounter = 1时,我得到的答案是错误的。

#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 个答案:

答案 0 :(得分:1)

指针算法(包括索引到数组)是静态的。它不知道您正在访问的对象的动态类型。因此,如果您使用指向派生对象数组的基指针,并尝试递增此指针,则会出现问题,因为指针算术假定指向的对象确实一个基础对象。

如果您真的想要使用数组的多态行为,则必须使用指针数组,并使returnArray函数返回base**

答案 1 :(得分:1)

问题是sizeof(Base)= 8,当arrayCounter在returnArray(&#39; m&#39;)[arrayCounter]中从0增加到1时,地址更改为8,但sizeof(myStruct)= 16,地址从MS [0]更改为16 [2],如代码所示

如果您希望这种情况发生,您可以更改指针类型

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

下面的代码列表输出:

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

答案 2 :(得分:1)

因为您的函数returnArray()返回base数组,而operator []实际上根据元素大小smth计算偏移量,如下所示:

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

因此,当您传递base数组时,此运算符会将其大小计算为sizeof(int) + sizeof(int)。 Polymorphysm仅适用于指针。所以它会像这样myStruct* a[10] 或者你可以只返回一个myStruct数组:myStruct* returnArray();

还有一件事。如果最终你将创建一个甚至比myStruct更大的派生类并尝试将它存储在数组中你将会成功但是你将存储的对象将缩小到myStruct的大小你会丢失数据。

答案 3 :(得分:0)

myStruct* returnArray(char c)将解决您当前的问题。但是如果你想在你的代码中使用很多派生类,你仍会感到困惑。

以下代码可能是更好的选择:

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

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