You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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++三五法则,手动补充如下逻辑:

  1. 析构函数中添加delete[] name;释放已申请的堆内存
  2. 自定义拷贝构造函数,重新申请内存并拷贝字符串内容
  3. 自定义拷贝赋值运算符,处理自赋值、释放旧内存、申请新内存拷贝内容的逻辑
    即可解决浅拷贝导致的崩溃问题。

内容的提问来源于stack exchange,提问作者dbz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 08:36:04