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

创建动态分配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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:02:24