c++ - 为什么 linux 不能捕获 C++ 运行时错误,例如使用浅拷贝构造函数?

标签 c++ linux

<分区>

我正在研究 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;
}

当我在 windows 10(由 visual studio 2017 编译)上编译并运行它时,它运行良好(发生运行时错误)但它在 linux 上运行不正常(由 g++ 7.3.0 编译)(运行-time 错误不会发生)。 linux 显示没有错误发生。

因此,我在 Linux 上调试该代码。我用的是 gdb。

after object daughter maked ---
1,Kitae
1,Kitae
daughter name changed ---
1,Grace
1,Grace
[Inferior 1 (process 3297) exited normally]

可以像那个代码一样使用浅拷贝构造函数吗?如果不是,为什么 windows 和 linux 显示不同的结果?

最佳答案

浅拷贝只是间接导致了bug。真正导致错误的是指针被删除了两次,因为浅拷贝。并且由于双重删除而发生的错误取决于编译器和操作系统。

如果你想在 Linux 上捕获类似的错误,有一个非常好的工具,叫做 valgrind。只需运行:

$ valgrind ./my_program

它会告诉您是否有任何内存泄漏或双重释放。

或者在编译程序时使用另一位评论者提到的地址清理器。 (它确实使代码运行得更慢,但这对于调试版本来说是可以的)。

话虽如此,并非所有浅拷贝都是坏的,浅拷贝构造函数有完全有效(且安全)的用例。例如,假设我正在编写自己的 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; 
        }
    }
};

在这里,shared_ptr 跟踪该指针有多少个实例,如果它是最后一个拷贝,它只会删除该指针。

关于c++ - 为什么 linux 不能捕获 C++ 运行时错误,例如使用浅拷贝构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55529700/

相关文章:

C++:指针、循环变量和结构的问题

c++ - QSqlRelationalTableModel QTableView 着色行

c++ - 如何防止 C++ 中不同别名类型的组合?

java - 如何解决 "Could not find JNI",在 Raspberry Pi 上构建 OpenCV?

linux - 从 shell 脚本将 Azure CLI 作为 cron 作业执行

java - 如何在Linux环境下为Tomcat实例设置java -Djava.library.path ="\home\path.SomeFile.so"?

c++ - 显式实例化模板类的显式实例化模板方法

c++ - 如何在mac终端编译c++程序

linux - svn 导出在命令行上工作,但在 shell 脚本中不工作

linux - Bash命令行重命名通配符