C++代码运行出现core dumped段错误的原因排查咨询
段错误触发的直接原因
- 你的默认构造函数将
nume指针直接指向了字符串字面量"o_marca":C++中字符串字面量存储在只读数据段,本身是const char*类型,你通过强制类型转换(char*)"o_marca"丢弃了const属性,属于未定义行为。调用setNume时执行strcpy(this->nume, (char*)nume),本质是往只读内存地址写入数据,操作系统直接触发段错误终止程序。
代码中还存在的其他致命隐患
- 带参构造函数未初始化
nume成员:你定义的5参数构造函数只给其他四个成员赋值,传入的nume参数完全没有被处理,this->nume会是野指针,只要访问/修改就会触发非法内存访问。 - 浅拷贝后续会触发double free:你现在的析构函数没有释放
nume指向的内存,所以暂时没有触发该问题。如果后续你补充了delete[] nume的逻辑,栈对象m2出作用域析构时会先释放一次内存,后续delete m1时会再次释放同一块内存,直接触发double free报错。 setNume实现完全不符合安全要求:strcpy不会检查目标缓冲区的长度,就算你给nume分配了堆内存,只要传入的新字符串长度超过原有缓冲区大小,就会触发缓冲区溢出,破坏内存结构。
修复方案
你需要按照深拷贝的规则重新实现类的核心函数:
- 所有构造函数都为
nume分配独立的堆内存,拷贝传入的字符串内容 - 显式实现拷贝构造函数、拷贝赋值运算符,完成深拷贝
- 析构函数中释放
nume的堆内存,避免泄漏 - 修改
setNume的实现,先释放旧内存再分配匹配长度的新内存存储新字符串
修复后代码示例
#include <iostream> #include <cstring> class Masina{ private: long long putere; int viteza; double masa; bool calificativ; char* nume; public: Masina();//默认构造 Masina(long long putere,int viteza,double masa,bool calificativ,const char* nume);//带参构造,参数改为const char*更合理 Masina(const Masina& other);//拷贝构造 Masina& operator=(const Masina& other);//拷贝赋值运算符 ~Masina();//析构 void setPutere(long long putere); void setViteza(int viteza); void setMasa(double masa); void setCalificativ(bool calificativ); void setNume(const char* nume); long long getPutere() const; int getViteza() const; double getMasa() const; bool getCalificativ() const; const char* getNume() const;//返回const char*避免外部修改内部内存 }; //默认构造 Masina::Masina(): putere(2000), viteza(250), masa(1.5), calificativ(false) { // 为nume分配堆内存,拷贝字面量内容 int len = strlen("o_marca"); nume = new char[len + 1]; strcpy(nume, "o_marca"); } //带参构造 Masina::Masina(long long putere,int viteza,double masa,bool calificativ,const char* nume): putere(putere), viteza(viteza),masa(masa),calificativ(calificativ) { int len = strlen(nume); this->nume = new char[len + 1]; strcpy(this->nume, nume); } //拷贝构造(深拷贝) Masina::Masina(const Masina& other): putere(other.putere), viteza(other.viteza), masa(other.masa), calificativ(other.calificativ) { int len = strlen(other.nume); this->nume = new char[len + 1]; strcpy(this->nume, other.nume); } //拷贝赋值运算符(深拷贝,处理自赋值情况) Masina& Masina::operator=(const Masina& other) { if(this == &other) return *this; // 先释放原有内存 delete[] nume; // 拷贝成员 putere = other.putere; viteza = other.viteza; masa = other.masa; calificativ = other.calificativ; int len = strlen(other.nume); nume = new char[len + 1]; strcpy(nume, other.nume); return *this; } //析构函数 Masina::~Masina() { std::cout << "putere: "<<putere<<"\nviteza: "<<viteza<<"\nmasa: "<<masa<<"\ncalificativ: "<<calificativ<<"\nnume: "<<nume; std::cout<<"\nobiectul a fost sters\n\n"; // 释放nume的堆内存 delete[] nume; } //setter实现 void Masina::setPutere(long long putere) { this->putere = putere; } void Masina::setViteza(int viteza) { this->viteza = viteza; } void Masina::setMasa(double masa) { this->masa = masa; } void Masina::setCalificativ(bool calificativ) { this->calificativ = calificativ; } void Masina::setNume(const char* nume) { // 先释放旧内存 delete[] this->nume; // 分配新内存再拷贝 int len = strlen(nume); this->nume = new char[len + 1]; strcpy(this->nume, nume); } //getter实现 long long Masina::getPutere() const { return putere; } int Masina::getViteza() const { return viteza; } double Masina::getMasa() const { return masa; } bool Masina::getCalificativ() const { return calificativ; } const char* Masina::getNume() const { return nume; } int main(){ Masina* m1 = new Masina(); { Masina m2 = *m1; m2.setNume("o_barca"); std::cout << "m1 nume: " << m1->getNume() << "\nm2 nume: " << m2.getNume() << std::endl; } delete m1; return 0; }
如果你确实需要两个对象的nume指向同一块内存实现同步修改,需要额外添加引用计数逻辑,避免double free问题。
内容的提问来源于stack exchange,提问作者pauk
相关产品推荐
相关产品推荐

