我正在将一些代码移植到另一个结构:
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'
有时它会出现段错误:
mY[i] += mYSpeed[i];
我无法想象它可能是什么,因为代码很旧并且有效。新的只是基类。
当我在启动应用程序时查看RAM使用情况时,我看到差不多+600 mb!
答案 0 :(得分: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]
中的此崩溃:
当您通过指向无处的指针调用此函数时,可能会发生这种情况。
答案 1 :(得分:5)
在初始化之前,您在init()
中使用了mMaxObjects。所以它有随机值。
void EnvironObject::init(int maxObjects)
{
mX = mY = mXSpeed = mYSpeed = std::vector<float>(mMaxObjects); // you mean maxObjects here
答案 2 :(得分:4)
我想你要替换
void EnvironObject::init(int maxObjects)
{
mX = mY = mXSpeed = mYSpeed = std::vector<float>(mMaxObjects);
与
void EnvironObject::init(int maxObjects)
{
mX = mY = mXSpeed = mYSpeed = std::vector<float>(maxObjects);
注意在矢量创建中将mMaxObject替换为maxObjects。
答案 3 :(得分:4)
一条评论虽然不太可能修复你的内存错误,但由于字段mX,mY,mXSpeed和mYSpeed似乎相关且矢量大小相同,你应该考虑将它们合并到一个结构中四个成员,并有一个包含几个结构实例的向量。