创建动态分配char数组时触发Segmentation Fault(段错误)求助
解决你的C++段错误问题
嘿,我帮你揪出了代码里引发Segmentation Fault的几个核心问题,咱们一个个拆解并修复:
1. setZichara函数的空指针解引用
你的PlaninarskiDom构造函数里把zich初始化为0(也就是空指针),但在setZichara里,当isZichara为0时,直接调用zich->copy(z)——这相当于对空指针调用成员函数,必然触发段错误。
正确的做法是先为zich分配内存,利用拷贝构造函数创建新对象:
void setZichara(Zichara &z) { if(isZichara == 0) { zich = new Zichara(z); isZichara = 1; } }
2. 浅拷贝导致的双重释放
PlaninarskiDom的copy函数里,zich = from.zich是直接赋值指针,这会让两个PlaninarskiDom对象指向同一块Zichara内存。当这两个对象析构时,都会尝试释放这块内存,引发双重释放的未定义行为(大概率会崩溃或段错误)。
要修复这个问题,需要实现深拷贝:
void copy(const PlaninarskiDom &from) { strcpy(name, from.name); star = from.star; isZichara = from.isZichara; // 深拷贝Zichara对象 if(from.zich != nullptr) { zich = new Zichara(*from.zich); } else { zich = nullptr; } for(int i = 0; i < 2; i++) { prices[i] = from.prices[i]; } }
3. 析构函数的错误内存释放
zich是单个Zichara*指针,不是动态数组,但你在析构函数里用了delete [] zich——delete []是专门用来释放数组内存的,用在单个对象指针上会导致未定义行为。
修正后的析构函数:
~PlaninarskiDom() { delete zich; // 释放单个对象,而非数组 }
完整修正后的代码
#include<iostream> #include<string.h> using namespace std; class Zichara { private: char *name; int price; void copy(const Zichara &from) { name = new char[strlen(from.name) + 1]; strcpy(name, from.name); price = from.price; } public: Zichara(const char *name, int price) { this->name = new char[strlen(name) + 1]; strcpy(this->name, name); this->price = price; } Zichara(const Zichara &from) { copy(from); } ~Zichara() { delete [] name; } friend class PlaninarskiDom; }; class PlaninarskiDom { private: char name[15]; int prices[2]; char star; bool isZichara; Zichara *zich; void copy(const PlaninarskiDom &from) { strcpy(name, from.name); star = from.star; isZichara = from.isZichara; // 深拷贝Zichara if(from.zich != nullptr) { zich = new Zichara(*from.zich); } else { zich = nullptr; } for(int i = 0; i < 2; i++) { prices[i] = from.prices[i]; } } public: PlaninarskiDom(const char *name = "", int prices = 0, const char star = '\0') { strcpy(this->name, name); this->star = star; isZichara = false; zich = nullptr; this->prices[0] = 0; this->prices[1] = 0; } PlaninarskiDom(const char *name, int *prices, const char star) { strcpy(this->name, name); this->star = star; isZichara = false; zich = nullptr; this->prices[0] = prices[0]; this->prices[1] = prices[1]; } PlaninarskiDom(const PlaninarskiDom &from) { copy(from); } ~PlaninarskiDom() { delete zich; // 修正释放方式 } PlaninarskiDom& operator = (const PlaninarskiDom &from) { if(this == &from) return *this; delete zich; // 先释放当前对象的zich copy(from); return *this; } void setZichara(Zichara &z) { if(!isZichara) { zich = new Zichara(z); // 用拷贝构造创建新对象 isZichara = true; } } };
额外注意点
- 尽量用
nullptr代替0来表示空指针,代码可读性更好 - 可以考虑在
Zichara里重载赋值运算符,确保拷贝操作的安全性 - 对字符串的操作,C++里更推荐用
std::string代替char*,能避免很多手动内存管理的问题
内容的提问来源于stack exchange,提问作者Nikita Kalpakovski
相关产品推荐
相关产品推荐

