C++数组初始化触发Segmentation error 不同IDE运行表现异常求助
问题原因及修复方案
核心错误点
- 浅拷贝导致野指针/重复释放
Point类包含堆分配的char* name成员,但未自定义拷贝构造函数、拷贝赋值运算符,编译器生成的默认拷贝为浅拷贝,仅复制指针地址,不会复制指针指向的内存内容。你在main函数中把circles0、circles1拷贝到circles数组时,多个对象的name指针指向同一块堆内存,程序结束析构时会重复释放同一块内存,属于未定义行为,大概率触发段错误。 getName函数逻辑错误
当前getName返回值为char类型,仅能返回字符串的第一个字符,无法获取完整名称,需修改为返回const char*或字符串类型。- 堆内存未正确释放
Point构造函数中用new char[20]申请了堆内存,但析构函数为空实现,没有对应的delete[] name,会导致内存泄漏。 - Dev-C++可运行属于侥幸
开启调试信息后不崩溃只是未定义行为的随机表现,调试模式下的内存布局和发布模式不同,刚好避开了崩溃触发条件,不代表代码本身没有问题。
修复方案
新手推荐直接使用std::string代替char*管理字符串,无需手动处理内存和拷贝逻辑,修复后代码如下:
#include <iostream> #include <iomanip> #include <string> using namespace std; class Point { protected: int y, x; string name; public: Point() { int newX, newY; cout << "Enter value for X: "; cin >> newX; setX(newX); cout << "Enter value for Y: "; cin >> newY; setY(newY); cout << "Enter name: "; cin >> name; } int getX() { return x; } int getY() { return y; } const string& getName() { return name; } void setX(int new_x) { x = new_x; } void setY(int new_y) { y = new_y; } void setName(const string& newName) { name = newName; } void showXY() { cout << "\nX: " << getX() << "\nY: " << getY(); } ~Point() = default; }; class Circle { int radius; Point point; public: Circle() { int r; cout << "Enter radius: "; cin >> r; setRadius(r); } int getRadius() { return radius; } void setRadius(int r) { radius = r; cout << "Radius " << radius << "\n"; } void showAll() { cout << "Name: " << point.getName(); point.showXY(); cout << "\nRadius: " << getRadius(); } ~Circle() = default; }; int main() { Circle circles0; Circle circles1; Circle circles[] = { circles0, circles1 }; for(int i=0; i<2; i++) { int r = circles[i].getRadius(); if(r > 4) { circles[i].showAll(); } } return 0; }
如果必须使用char*实现,需要遵循C++三五法则,手动补充如下逻辑:
- 析构函数中添加
delete[] name;释放已申请的堆内存 - 自定义拷贝构造函数,重新申请内存并拷贝字符串内容
- 自定义拷贝赋值运算符,处理自赋值、释放旧内存、申请新内存拷贝内容的逻辑
即可解决浅拷贝导致的崩溃问题。
内容的提问来源于stack exchange,提问作者dbz
相关产品推荐
相关产品推荐

