我一直在阅读delete[]
,new[]
,what-is-the-rule-of-three,
deallocating-objects-stored-in-a-vector,delete-vector-class-member并遇到
抛出异常:读取访问冲突。
我已经定义了一个基类
class Person
{
private:
std::string name;
int age;
static int cur_id;
public:
Person() {}
Person(std::string new_name, int new_age) : name(new_name), age(new_age) { cur_id += 1; }
virtual ~Person() {}
void setname(std::string name) { this->name = name; }
std::string getname() { return name; }
int getage() { return age; }
void setage(int age) { this->age = age; }
int get_id() { return cur_id; }
virtual void getdata(void) = 0;
virtual void putdata(void) = 0;
};
派生类
class Professor : private Person
{
private:
int publications;
Professor* prof;
public:
Professor() {}
Professor(std::string new_name, int new_age, int new_pubs) : Person(new_name, new_age) { this->publications = new_pubs; }
~Professor() override { delete prof; }
void getdata() override
{
std::vector<std::string> prof_input = get_input();
std::cout << prof_input[0] << "\n";
std::cout << std::stoi(prof_input[1]) << "\n";
std::cout << std::stoi(prof_input[2]) << "\n";
prof = new Professor(prof_input[0], std::stoi(prof_input[1]), std::stoi(prof_input[2]));
}
void putdata() override
{
std::cout << prof->getname() << " " << prof->getage() << " " << prof->publications << " " << prof->get_id();
}
};
并定义了主要
int main()
{
int size;
std::cin >> size;
std::cin.ignore();
Professor* prof = new Professor();
std::vector<Professor> prof_vec;
for (int i = 0; i < size; i++)
{
int which;
std::cin >> which;
std::cin.ignore();
switch (which)
{
case 1:
{
prof->getdata();
prof_vec.push_back(*prof);
}
break;
case 2:
{
// something else
}
break;
}
}
for (auto prof : prof_vec)
{
prof.putdata();
} <<< ------------------- Things so south here
delete prof;
fgetc(stdin);
return 0;
}
我想到的是(假设向量中只有一个元素),一旦调用putdata()
退出块,析构函数调用delete prof
就会出现
this-&gt; prof是0xCDCDCDCD。
我正在尝试删除不存在的对象。如果我想确保delete
正确,即使有这样一个简单的例子,我应该做些什么来确保没有内存泄漏?
答案 0 :(得分:4)
您违反了rule of 3/5/0:
class Professor : private Person
{
private:
Professor* prof;
public:
// ...
~Professor() override { delete prof; }
};
如果您提供其中一个特殊成员函数,则应提供所有特殊成员函数。在这种情况下,您的复制构造函数只是成员复制Professor*
,现在您有两个不同的对象试图删除相同的指针。
首选规则0:
class Professor : private Person
{
private:
std::unique_ptr<Professor> prof;
public:
// ...
~Professor() = default;
};
答案 1 :(得分:2)
成员Professor* prof
未在构造函数Professor()
中初始化,仅在getdata();
初始化
当代码转到案例2时,如果没有对getdata()
的任何调用,则prof
将保持未初始化状态。
0xCDCDCDCD
表示调试模式中未初始化的值。