不知道出了什么问题 - 两次程序隔离错误
Not sure what's wrong -- Program Segfaults on two occasions
我正在使用SDL创建一个非常简单的Pong游戏。对于碰撞检测,我有一个名为DetectCollision的类,看起来像这样:
class DetectCollision {
public:
std::vector<Object*> objects;
int numOfObjects;
DetectCollision();
~DetectCollision();
void takeObjs(Object &);
void handleCollision();
};
因此,takeObjs(Object &)函数接受Object类的对象并将其存储在vector中。takeObjs(Object &)看起来像这样:
void DetectCollision::takeObjs(Object &obj1){
objects.push_back(&obj1);
}
到目前为止一切都很顺利。我能够访问矢量"对象"来检测所有的碰撞,它工作得很好,但当我试图删除矢量时,问题就来了。如果我没记错的话,它是一个指针向量。我在类析构函数中删除了它:
DetectCollision::~DetectCollision(){
for (unsigned int i = 0; i < objects.size(); ++i){
delete objects[i];
}
objects.clear();
}
根据Code::Blocks IDE使用GCC编译器,它在"delete objects[i];"行上出现分段错误。它还对程序的另一部分进行分段错误,以尝试SDL_FreeSurface()类持有的皮肤,但我认为我可以很容易地修复这个问题。这个向量是主要问题。如果您需要查看完整的源代码来帮助我了解如何解决这个问题,我可以提供。我非常感谢任何帮助。谢谢,DFTBA!
当析构函数被调用时,你的应用程序会出现分段错误,因为这些对象已经不存在了。
takeObjs
方法接收到一个对象的引用,然后在vector中存储指向该对象的指针。该对象在其他地方定义。当该对象超出作用域时,它将被自动销毁。
到达析构函数时,对象已被销毁。由于您试图再次销毁它,应用程序出现了分段故障。
你应该阅读c++中对象的作用域(阅读这个问题的答案),你还应该阅读c++中的对象销毁。
编辑:添加简短的例子来说明崩溃
#include <iostream>
#include <vector>
using namespace std;
class Object {
public:
int a;
int b;
Object(int a, int b)
{
this->a=a;
this->b=b;
}
};
class Test
{
std::vector<Object*> objects;
public:
Test(){}
void Add(Object &obj)
{
objects.push_back(&obj);
}
void Print()
{
for(unsigned int i=0;i<objects.size();i++)
{
cout<<objects[i]->a<<" "<<objects[i]->b<<endl;
}
}
~Test()
{
for (unsigned int i = 0; i < objects.size(); ++i){
delete objects[i];
}
objects.clear();
}
};
void AddNewObjects(Test &t)
{
Object x(1,2);
Object y(3,4);
t.Add(x);
t.Add(y);
// you can access your objects here
t.Print();
}
int _tmain(int argc, _TCHAR* argv[])
{
Test t;
AddNewObjects(t);
// but if you try to access the objects here, you get a crash
// because the objects were destroyed when exiting "AddNewObjects"
t.Print();
return 0;
// your destructor tries to access the objects here (in order to destroy them)
// and that's why it crashes
}
这里有一个你可以用来解决这个问题的解决方案:
#include <iostream>
#include <vector>
using namespace std;
class Object {
public:
int a;
int b;
Object(int a, int b)
{
this->a=a;
this->b=b;
}
};
class Test
{
std::vector<Object*> objects;
public:
Test(){}
void Add(Object *pObj)
{
objects.push_back(pObj);
}
void Print()
{
for(unsigned int i=0;i<objects.size();i++)
{
cout<<objects[i]->a<<" "<<objects[i]->b<<endl;
}
}
~Test()
{
for (unsigned int i = 0; i < objects.size(); ++i){
delete objects[i];
}
objects.clear();
}
};
void AddNewObjects(Test &t)
{
Object* x = new Object(1,2);
Object* y = new Object(3,4);
t.Add(x);
t.Add(y);
// you can access your objects here
t.Print();
}
int _tmain(int argc, _TCHAR* argv[])
{
Test t;
AddNewObjects(t);
// you can also access the objects here
// because they are not destroyed anymore when exiting "AddNewObjects"
t.Print();
return 0;
}
一个潜在的问题是DetectCollision
违反了三原则。如果复制一个实例,该副本将得到相同的Object
指针的向量,最终导致双delete
。
你可能有一个双重删除,因为传递给DetectCollision类的对象在其他地方被删除了,可能是因为它们超出了作用域。
你必须考虑谁将"拥有"这些对象。
- 当同一个程序被打开两次时,如何使用C ++杀死一个程序?
- 基于 MFC 对话框的应用程序无法调用对话框两次
- 程序在运行两次后关闭
- C++使用二维数组的程序,该数组要求用户输入两次.它需要将这些输入显示为输出
- 阵列不能两次将相同的名称保存,当要添加新字符串时,程序应检查以查看该名称是否已经存在
- 为什么这个程序打印"nine"两次?
- 在同一程序中调用srand()两次
- 为什么这个程序中的析构函数被调用两次
- 为什么这个C++/OpenGL程序运行两次
- C++程序要求我输入两次,即使变量第一次被分配
- 我是否需要锁才能同时使用同一应用程序两次写入套接字
- 多次定义"调度程序::_singleton",导入标头两次
- 程序写入记录在 C++ 的二进制文件中两次
- c ++:TCP服务器"bind"功能失败(errno 98),如果我在两次连续应用程序启动之间没有等待足够的时间
- C++程序 尝试连续运行两次写入循环时显示".. stopped working"错误
- 为什么在这个树程序中,我得到了两次输出
- 我正在尝试递归地实现一个程序。我只是不明白为什么我的最后一行被执行了两次
- 为什么我的程序不崩溃,如果析构函数被调用两次
- 在程序中运行程序,两次
- 不知道出了什么问题 - 两次程序隔离错误