我正在研究c ++复制构造函数。我编写了使用浅拷贝构造函数的代码,该构造函数会导致运行时错误进行研究。我的意图是使运行时错误。
#include <iostream>
#include <cstring>
using namespace std;
class Person{ //define Person class
char *name;
int id;
public:
Person(int id, const char *name);//constructer
~Person();//distructer
Person(Person& p){
this->name = p.name;
this->id = p.id;
}
void changeName(const char *name);
void show(){
cout << id <<',' << name <<endl;
}
};
Person::Person(int id, const char *name){
this -> id = id;
int len = strlen(name);
this->name = new char[len+1];
strcpy(this->name,name);
}
Person::~Person(){
if(name)
delete []name;
}
void Person::changeName(const char *name){
if(strlen(name) > strlen(this->name))
return;
strcpy(this->name,name);
}
int main(){
Person father(1,"Kitae");
Person daughter(father);
cout << "after object daughter maked ---" << endl;
father.show();
daughter.show();
daughter.changeName("Grace");
cout <<"daughter name changed ---"<<endl;
father.show();
daughter.show();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当我在Windows 10(由Visual Studio 2017编译)上编译并运行它时,它运行良好(发生运行时错误),但在linux(由g ++ 7.3.0编译)上却无法正常运行(运行时错误不会发生)。linux显示没有错误发生。
因此,我在Linux上调试了该代码。我用过gdb。
after object daughter maked ---
1,Kitae
1,Kitae
daughter name changed ---
1,Grace
1,Grace
[Inferior 1 (process 3297) exited normally]
Run Code Online (Sandbox Code Playgroud)
像这样的代码使用浅表复制构造函数可以吗?如果不是,为什么Windows和Linux显示不同的结果?
浅表副本仅间接导致错误。导致错误的真正原因是指针由于浅拷贝而被删除了两次。并且由于双重删除而发生的错误取决于编译器和操作系统。
如果您想在Linux上捕获类似的错误,则有一个非常好的工具valgrind。赶紧跑:
$ valgrind ./my_program
Run Code Online (Sandbox Code Playgroud)
它会告诉您是否存在内存泄漏或两次释放。
或在编译程序时使用另一个评论者提到的地址清理器。(它的确使代码运行速度变慢,但是对于调试版本是可以的)。
话虽这么说,并不是所有浅表副本都是坏的,并且浅表副本构造函数有完全有效(且安全)的用例。例如,假设我正在编写自己的shared_ptr课程。实现非常简单:
template<class T>
class shared_ptr {
T* ptr;
int* counter;
void increment_counter() {
int& count = *counter;
++count;
}
int decriment_counter() {
int& count = *counter;
return --count;
}
public:
explicit shared_ptr(T* ptr)
: ptr(ptr)
, counter(new int(1))
{}
// Make shallow copy, but increment the counter
shared_ptr(shared_ptr const& other)
: ptr(other.ptr)
, counter(other.counter)
{
increment_counter();
}
~shared_ptr() {
int new_count = decriment_counter();
// Only delete the pointer if this was the last copy
if(new_count == 0) {
delete ptr;
delete counter;
}
}
};
Run Code Online (Sandbox Code Playgroud)
在这里,shared_ptr跟踪该指针有多少个实例,并且仅当指针是最后一个副本时才删除该指针。
| 归档时间: |
|
| 查看次数: |
103 次 |
| 最近记录: |