指向对象数组的指针作为成员覆盖内存

时间:2013-01-10 14:37:36

标签: c++ arrays class object

这是合约。我们有2个不同的类F类和O类

class F {
    private:
        int x;
        int y; 
    public:
        int getXf(){ return x; }
        int getYf(){ return y; }
        f(int ,int);
};

class O {
    private:
        int n;
        int k;
        int x;
        int y;
        char type;
        int id;
        int t;
    public:
        O(int ,int ,int ,int ,int);
        int getX(){ return x; }
        int getY(){ return y; }
};

我们有一个第三类P,我们在其中初始化值。在类中,我们创建了两个对象数组。

class Prog {                                                                   
    public:
        int count;
        int fcount;
        O *o[]; //here we are declaring the arrays of objects
        F *f[];           
    public :
        //void init(); Here is the function where we initializing the values
};

现在我们正在创建对象的2个语句。

for(int i=0;i<10;i++){
        randx = rand() % 10;
        randy = rand() % 20;

        o[i] = new O(100,50,i,randx,randy);
    }


    for(int i=0;i<3;i++){
        randx = rand() % 10;
        randy = rand() % 10;

        f[i] = new F(randx, randy);
    }

当我们打印时,所有对象都在这里,但是第一个类的前3个被秒的对象替换。完全是10050(第一个)分别来自randxrandy(第二个)。

3 个答案:

答案 0 :(得分:6)

O *o[];

这声明了一个未知大小的数组,这是一个不完整的类型。 C ++不允许将其用作类成员,尽管某些编译器会将其作为扩展,将其解释为零大小的数组。无论哪种情况,都不是你想要的。

如果您知道在编译时绑定的数组,那么您应该指定它:

O *o[10];

否则,您需要在运行时动态分配数组:

std::vector<O*> o;

for(int i=0;i<10;i++){
    randx = rand() % 10;
    randy = rand() % 20;

    o.push_back(new O(100,50,i,randx,randy));
}

我还建议存储对象,或者可能是智能指针,而不是数组中的原始指针。如果由于某种原因确实需要原始指针,那么请记住在完成对象后删除这些对象,因为这不会自动发生,并且不要忘记Rule of Three

答案 1 :(得分:5)

您正在声明数组,但您永远不会为它们分配内存。您所看到的就是您的代码遍布整个堆栈的方式。

更合适的事情:

struct X {}; struct Y {};

class P {
public:
  P() : xs(new X*[10]), ys(new Y*[10]) { init(); }

  ~P() {
    // delete all objects
    for(std::size_t i = 0; i < 10; ++i)
      delete xs[i];
    for(std::size_t i = 0; i < 10; ++i)
      delete ys[i];

    delete[] xs;
    delete[] ys;
  }
private:
  void init() {
    // initialize
    for(std::size_t i = 0; i < 10; ++i)
      xs[i] = new X();
    for(std::size_t i = 0; i < 10; ++i)
      ys[i] = new Y();
  }

  // prevent assignment and copy
  P& operator=(const P& other);
  P(const P&);

  X** xs;
  Y** ys;
};

当然,如果您只是使用,所有这些魔法都变得不必要了 std::vector来存储您的数据。

答案 2 :(得分:1)

问题是由于您声明数组的方式:

O *o[/*No size here*/];
F *f[/*No size here*/];

由于您没有说明数组的大小,这相当于

O **o;
F **f;

因此,您分别声明了两个类型的成员“指向指向O的指针”指向指向F的指针,但这些是未初始化的,你有没有分配任何内存供他们指出。也就是说,你实际上没有任何数组,只是可以用来指代你想要的数组类型的指针。

如果您在编译时知道要使用的大小,则应在声明中指定该大小,这将为您提供该大小的正确分配数组。否则,请考虑使用std::vector