你能告诉我这个代码为什么崩溃吗
could you tell me why does this code crash?
所以我很好奇以下代码崩溃的原因。将感谢帮助。
#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;
}
您违反了的三条规则
您维护一个指针成员,并将对象的副本传递给函数f
。因此,最终结果是在同一指针上调用delete
两次。
由于传递x
的方式而发生崩溃。
在f
函数的作用域之后,将调用x
的析构函数并删除intPtr
。
但是,这将删除仍在main
作用域中的内存。因此,在调用return 0
之后,它将尝试删除已经存在的内存,因为您在同一指针上调用了两次delete。
要修复此错误,请更改
void f (temp fInput)
至
void f (const temp& fInput)
或者,您可以考虑使用std::shared_ptr。
当传递x(隐式复制构造函数)时,指针被复制,析构函数被调用两次(函数返回之前和main返回之前),因此内存被删除两次。
此处使用std::shared_ptr<int>
而不是原始int指针(假设您希望行为相同,即从两个temp
引用相同的int
;否则,请自己实现复制构造函数、移动构造函数和赋值运算符)。
#include <memory>
class temp {
public:
temp(int i) : intPtr(std::make_shared<int>(i)) {
}
private:
std::shared_ptr<int> intPtr; // reference counting ftw
};
您在这里遇到的问题是双重删除。因为您没有在这里定义任何复制构造函数,C++很乐意为您定义。该实现通过执行所有内容的浅层复制来实现这一点。
f(x);
这一行通过创建x
的副本并将其传递给f
来工作。此时,有2个temp
实例拥有一个intPtr
成员。两个实例都会删除该指针,这很可能是导致崩溃的原因。
要解决这个问题,你可以采取一些步骤
- 使用用于共享的指针类型,如
shared_ptr<T>
- 创建一个不可调用的副本构造函数,强制实例由ref传递
#2的一个例子是
class temp {
temp(const temp& other);
temp& operator=(const temp& other);
public:
// Same
};
现在f(x)
行根本无法编译,因为它无法访问必要的复制构造函数。它强制它重新定义f
以防止复制。
void f(const temp& fInput) {
...
}
相关文章:
- 为什么所有C++编译器都会崩溃或挂起此代码
- 为什么lambda在clang上崩溃而不是在gcc上崩溃
- 为什么我的多线程作业队列崩溃
- 为什么引用传递会导致此崩溃(C++)
- 排序时无法执行交换操作.我做的时候它会崩溃.为什么
- 为什么要增加导致崩溃的指针
- 为什么它只打印双链接列表的第一个值,而我的程序却崩溃了
- 为什么当我尝试搜索双链表中第一个数据条目之外的数据时,程序崩溃了?
- 为什么从文件获取图标时应用程序有时会崩溃?
- 为什么gmp会在这里与"invalid next size"重新定位一起崩溃?
- 您好,我实际上想了解以下代码.有人可以详细说明代码它到底在做什么吗?为什么它会在第 31 行崩溃
- 为什么vector::eras似乎会导致崩溃?
- 为什么我的结构在包含字符串时崩溃?
- 为什么在同一条件变量上使用多个互斥锁会使此代码崩溃?
- 为什么这个程序在我插入前2个输入后崩溃
- 为什么代码会崩溃?(在CPP中)
- C++程序崩溃.为什么?
- 为什么抓取窗口标题的代码会导致应用崩溃?
- 类似的代码.一个工作,一个崩溃.为什么?
- 你能告诉我这个代码为什么崩溃吗