使用C ++:
我目前有一种方法,如果事件发生,则创建一个对象,并且指向该对象的指针存储在指向该类对象的指针向量中。但是,由于对象在本地作用域结束后被销毁,这是否意味着我存储到向量中的对象的指针现在为null或未定义?如果是这样,有什么通用的方法来解决这个问题 - 我假设最好的方法是在堆上进行分配。
我问这个是因为当我尝试访问向量并对内容进行操作时,我会遇到奇怪的行为,而且我不确定这是否可能是原因,或者它是否完全不相关。
答案 0 :(得分:4)
这取决于您如何分配对象。如果将对象分配为自动变量(即在堆栈上),则一旦对象超出范围,任何指向该对象的指针都将变为无效,因此取消引用指针将导致未定义的行为。
例如:
Object* pointer;
{
Object myobject;
pointer = &myobject;
}
pointer->doSomething(); // <--- INVALID! myobject is now out of scope
但是,如果使用new
运算符在堆上分配对象,则即使退出本地作用域,对象仍将保持有效。但是,请记住,C ++中没有自动垃圾收集,因此您必须记住delete
对象,否则您将发生内存泄漏。
答案 1 :(得分:1)
因此,如果我理解正确,您已经描述了以下情况:
class MyClass
{
public:
int a;
SomeOtherClass b;
};
void Test()
{
std::vector<MyClass*> b;
for (int i=0; i < 10; ++i)
{
MyClass b;
v.push_back(&b);
}
// now v holds 10 items pointers to strange and scary places.
}
这绝对是坏事。 有两个主要的选择:
std::vector<MyClass>
)我通常更喜欢第二种选择。这是因为我不必担心手动释放内存,向量为我做了。它通常也更有效率。唯一的问题是,我必须确保为MyClass创建一个复制构造函数。这意味着MyClass(const MyClass& other) { ... }
形式的构造函数。
答案 2 :(得分:0)
如果存储指向对象的指针,并且该对象被销毁(例如超出范围),则该指针不会为null,但如果您尝试使用它,则会得到未定义的行为。因此,如果向量中的一个指针指向堆栈分配的对象,并且该对象超出范围,则该指针将无法安全使用。特别是,没有办法判断指针是否指向有效对象;你只需要编写你的程序,指针永远不会永远指向被破坏的对象。
要解决此问题,您可以使用new为堆上的对象分配空间。然后在删除它之前不会销毁它。但是,这需要一点小心才能正确,因为你必须确保你的对象不会过早被破坏(留下另一个'悬挂指针'问题,就像你现在拥有的那个)或者太晚(造成内存泄漏)。
为了解决 ,C ++中的常用方法是使用所谓的(具有不同程度的准确性) smart 指针。如果你是C ++的新手,你可能不应该担心这些,但是如果你有野心(或者对内存破坏错误感到沮丧),请查看Boost库中的shared_ptr。
答案 3 :(得分:0)
如果你有一个局部变量,比如一个int计数器,那么当你退出函数时它会超出范围,但是,除非你有一个带有垃圾收集器的C ++,那么你的指针将在范围内,如你有一些指向你的对象的全局向量,只要你为指针做了new
。
我没有看到我做过new
的情况,没有我做任何事情,我的记忆被释放了。
答案 4 :(得分:0)
检查(无特定顺序):
您是否在构建存储指针的成员对象时遇到异常?
您在取消引用的容器中是否有空指针?
您是否在超出范围后使用vector
对象? (看起来不太可能,但我仍然要问。)
你正在清理吗?
以下是帮助您的示例:
void SomeClass::Erase(std::vector<YourType*> &a)
{
for( size_t i = 0; i < a.size(); i++ ) delete a[i];
a.clear();
}