2012-04-04 164 views
2

所以我很好奇下面的代码崩溃的原因。 会感谢您的帮助。你能告诉我为什么这段代码崩溃了?

#include <iostream> 
using namespace std; 

class temp 
{  
    public: 

    temp(int i) 
    { 
     intPtr = new int(i); 
    } 

    ~temp() 
    { 
     delete intPtr; 
    } 

    private: 
    int* intPtr; 
}; 

void f (temp fInput) 
{ 
    cout << "f called" << endl; 
} 

int main() 
{ 
    temp x = 2; 
    f(x); 
    return 0; 
} 
+1

你能定义“崩溃”吗? – josephthomas 2012-04-04 21:18:44

+0

@ Ed S:但是,我同意,有时候我们认为的崩溃可能与他认为的崩溃不同。 – josephthomas 2012-04-04 21:23:02

+0

@josephthomas:是的,我想到了很多,这就是为什么我发布后不久就删除了我的评论:)我们可以就术语的正确使用达成一致......是否大多数初学者会正确使用它是另一个问题 – 2012-04-04 21:23:41

回答

5

当x被传递(隐式拷贝构造)和析构函数被调用两次(在函数返回之前和前主退货)的指针被复制,因此,存储器被删除的两倍。

使用std::shared_ptr<int>这里,而不是代替原始INT指针(假设你想要的行为是相同的,即引用来自temp相同的S int;否则,执行拷贝构造函数,将构造函数和赋值操作符自己)。

#include <memory> 

class temp {  
public: 
    temp(int i) : intPtr(std::make_shared<int>(i)) { 

    } 

private: 
    std::shared_ptr<int> intPtr; // reference counting ftw 
}; 
+0

或者只是正确地实现类开始(即正确的复制语义等) – 2012-04-04 21:22:30

+0

这也是可能的,这取决于你想要的行为。 – 2012-04-04 21:23:25

+0

....正确的行为总是可取的。 – 2012-04-04 21:24:05

5

由于您通过的方式发生崩溃x

f函数的范围x的结构将被调用并将删除intPtr

但是,这将删除仍在范围内的存储器main。因此,在调用return 0之后,它将尝试删除已存在的内存,因为您在同一个指针上调用了两次删除操作。

要修正这个错误,改变

void f (temp fInput) 

void f (const temp& fInput) 

或者,你可以考虑使用一个std::shared_ptr

+0

添加一个拷贝构造函数和赋值操作符也是一个好主意。你也可以使用std :: shared_ptr而不是原始指针,因为它负责复制语义。 – 2012-04-04 21:25:10

+0

我同意,我想让海报知道一个解决方案,以最小的努力帮助他。有很多方法可以解决这个崩溃。 – josephthomas 2012-04-04 21:27:43

5

您违反了The Rule of Three

你保持一个指针成员,你传递对象的副本功能f。所以,最终的结果是你在相同的指针上调用delete两次。

1

您在这里遇到的问题是双重删除。因为你没有定义任何拷贝构造函数,所以C++很高兴为你做。该实现通过执行所有内容的浅表副本来完成。

f(x); 

该行通过创建的x副本,并将其传递给f。此时有2个temp实例,它们拥有一个intPtr成员。这两个实例都将删除该指针,这可能是导致您崩溃的原因。

要解决这一点,你可以采取一些步骤

  1. 使用意味着共享像shared_ptr<T>
  2. 指针类型创建uncallable拷贝构造函数强制实例由参传递

的#2的一个例子是

class temp { 
    temp(const temp& other); 
    temp& operator=(const temp& other); 
public: 
    // Same 
}; 

现在f(x)行根本无法编译,因为它无法访问必要的拷贝构造函数。它迫使它重新定义f以防止复制。

void f(const temp& fInput) { 
    ... 
} 
相关问题