2010-10-20 66 views
0

我移植一些代码,以另一种结构:代码需要太多的内存

class EnvironObject 
{ 
    protected: 
     vector<float> mX, mY, mXSpeed, mYSpeed; 
     int mMaxObjects; 

    public: 
     virtual void init(int maxObjects); 
     virtual void setLimit(int limit); 
     virtual int getLimit(); 
     virtual void update(float arg) = 0; 
}; 

void EnvironObject::setLimit(int limit) 
{ 
    mMaxObjects = limit; 

    mX.resize(limit, 0); mY.resize(limit, 0); 
    mXSpeed.resize(limit, 0); mY.resize(limit, 0); 
} 

int EnvironObject::getLimit() 
{ 
    return mMaxObjects; 
} 

void EnvironObject::init(int maxObjects) 
{ 
    mX = mY = mXSpeed = mYSpeed = std::vector<float>(mMaxObjects); 

    fill(mX.begin(), mX.end(), 0); 
    fill(mY.begin(), mY.end(), 0); 
    fill(mXSpeed.begin(), mXSpeed.end(), 0); 
    fill(mYSpeed.begin(), mYSpeed.end(), 0); 

    /*mX.reserve(mMaxObjects * 1.5); mY.reserve(mMaxObjects * 1.5); 
    mXSpeed.reserve(mMaxObjects * 1.5); mYSpeed.reserve(mMaxObjects * 1.5);*/ 

    mMaxObjects = maxObjects; 
} 

这是一些基本类,现在它的用法:

class Rain : public EnvironObject 
{ 
    public: 
     Rain(int maxDrops = 150); 
     void update(float windPower); 
}; 

Rain::Rain(int maxDrops) 
{ 
    srand(time(NULL)); 

    IEnvironObject::init(maxDrops); 
} 

void Rain::update(float windPower) 
{ 
    for (int i=0; i < mMaxObjects; i++) 
    { 
     mX[i] += mXSpeed[i]; 
     mY[i] += mYSpeed[i]; 

     mXSpeed[i] += windPower; 
     mYSpeed[i] += G; 

    // Drawing 
    } 
} 

默认构造函数的对象Rain创建(所以,每个数组都是150个元素大小),然后我打电话给setLimit(50)。 问题是,代码失败几乎每个异常运行:

terminate called after throwing an instance of 'std::bad_alloc' 

,有时出现segfaults在行:

mY[i] += mYSpeed[i]; 

我不能想象什么莫非,因为代码是旧的,有效。新的只是基础类。

当我在启动应用程序时查看内存使用情况时,我看到的差不多是+600 MB!再次

+0

你可以添加一个'main'函数来显示你如何调用这些/使用它们吗?在它的表面上,我看不到任何明显的错误... – 2010-10-20 19:43:42

+1

'init'函数是代码异味。这就是构造函数的用途。 – GManNickG 2010-10-20 20:01:06

+0

@GMain我可以从派生类调用基构造函数吗?导致编译器返回有关此的一些错误。 – Ockonal 2010-10-20 20:07:27

回答

7

看看你的那个功能:

void EnvironObject::init(int maxObjects) 
{ 
    mX = mY = mXSpeed = mYSpeed = std::vector<float>(mMaxObjects); 
    //            ^
    // ... 

    mMaxObjects = maxObjects; 
} 

您使用了尚未初始化的变量。

你的班级的一个大问题是你正在做所谓的两阶段建设。你的类EnvironObject有一个编译器提供的默认构造函数,它为所有POD类型创建一个具有随机值的对象(mMaxObjects)。然后用户需要调用init()方法来真正初始化该对象。但这就是构造函数的用处!

void EnvironObject::EnvironObject(int maxObjects) 
    : mMaxObjects(maxObjects) 
    , mX(maxObjects), mY(maxObjects), mXSpeed(maxObjects), mYSpeed(maxObjects) 
{ 
    /* these aren't necessary, std::vector automatically does this 
    fill(mX.begin(), mX.end(), 0); 
    fill(mY.begin(), mY.end(), 0); 
    fill(mXSpeed.begin(), mXSpeed.end(), 0); 
    fill(mYSpeed.begin(), mYSpeed.end(), 0); 
    */ 
} 

派生那么类可以使用这个构造:

Rain::Rain(int maxDrops) 
: EnvironObject(maxDrops) 
{ 
    srand(time(NULL)); 
} 

对此崩溃认购mY[i] += mYSpeed[i]

当你通过指针的调用此函数可能发生这种情况指向无处。

+0

感谢您的回复。 – Ockonal 2010-10-20 19:50:38

+0

哦,这太棒了。 – Ockonal 2010-10-20 20:08:31

+0

顺便说一句,最好删除4个数组,并使用该字段构造。并使结构向量? – Ockonal 2010-10-20 20:10:08

5

在初始化之前,您正在使用init()中的mMaxObjects。所以它有一个随机值。

void EnvironObject::init(int maxObjects) 
{ 
    mX = mY = mXSpeed = mYSpeed = std::vector<float>(mMaxObjects); // you mean maxObjects here 
4

我想你想与

void EnvironObject::init(int maxObjects) 
{ 
    mX = mY = mXSpeed = mYSpeed = std::vector<float>(maxObjects); 

通知更换mMaxObject到maxObjects在向量生成来取代

void EnvironObject::init(int maxObjects) 
{ 
    mX = mY = mXSpeed = mYSpeed = std::vector<float>(mMaxObjects); 

4

一个评论,尽管它不可​​能解决你的内存错误,但是由于字段mX,mY,mXSpeed和mYSpeed看起来相关且矢量大小相同,所以应该考虑将它们合并为一个结构有四个成员,并且有一个包含这些结构实例的单个向量。

+0

感谢您的提示;) – Ockonal 2010-10-20 19:50:20

+0

它实际上取决于,如果您计划一次一个地工作,分开各个字段是有意义的,这样您就不会填充你的缓存中有你不关心的值。不记得这个编程策略的名字,尽管... – 2010-10-21 06:56:28