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

自制模板Matrix类触发SIGSEGV错误,请求技术排查指导

排查你的模板Matrix类SIGSEGV错误

嘿,我来帮你一步步揪出导致段错误的元凶,先从几个最直接的问题说起:

1. 最致命的越界访问:selectedTab超出矩阵列范围

看你的MenUI构造函数:

MenUI::MenUI():selectedTab(3),selectedItem(4),menItems(matrix<string>(3,4)) {

你实例化的menItems是3列4行的矩阵(matrix构造函数第一个参数是列数),所以列的有效索引是0、1、2,但你把selectedTab初始化为3——这直接超出了列的合法范围!在print函数里执行menItems[selectedTab][i]时,相当于访问tabs[3],而tabs数组只有3个元素,这必然触发段错误。

2. Matrix析构函数的数组释放错误

你的matrix类析构函数写的是:

virtual ~matrix() { delete tabs; }

但tabs是用new vektor<T>[columns]分配的数组,释放数组必须用delete[],而不是delete。用错释放方式会导致内存泄漏和未定义行为,这也是段错误的常见诱因,赶紧改成:

virtual ~matrix() { delete[] tabs; }

3. 拷贝构造和赋值运算符的致命逻辑错误

你的拷贝构造函数和operator=都把数组指针当成单个对象处理了,这会直接导致内存越界:

  • 拷贝构造函数里,不仅写错了成员变量名(matrix类没有rows成员,应该是columns),还错误地用new vektor<T>(*other.getTabs())构造了单个vektor对象,而不是数组。后续访问tabs[index]时,本质是在单个对象的内存后面越界读写,必然崩溃。
  • 赋值运算符里还多了个拼写错误:spalten = rhs.getColCount();——matrix类的成员是columns,不是spalten。

正确的拷贝构造函数应该循环创建每个列的vektor:

matrix(const matrix& other):columns(other.getColCount()),tabs(new vektor<T>[columns]) {
    for(int i = 0; i < columns; ++i) {
        tabs[i] = other.tabs[i];
    }
}

正确的赋值运算符要先释放原有内存,再循环拷贝:

matrix<T>& operator=(const matrix& rhs) {
    if (this == &rhs) return *this; // 处理自赋值,避免重复释放

    // 先释放当前对象的内存
    delete[] tabs;

    columns = rhs.getColCount();
    tabs = new vektor<T>[columns];
    for(int i = 0; i < columns; ++i) {
        tabs[i] = rhs.tabs[i];
    }
    return *this;
}

4. Vektor类operator[]的const正确性问题

你的vektor类的operator[]是const成员函数,但返回的是非const引用:

T& operator[](const unsigned int index)const {
    if(index >= 0 && index < length) {
        return items[index];
    } else throw out_of_bounds();
}

在const成员函数里,items会被视为const T*,你不能返回T&(非const引用),这会导致编译错误(如果现在没报错可能是编译器宽松模式)。应该提供两个版本的operator[]:

// 非const版本:允许修改元素
T& operator[](unsigned int index) {
    if(index >= length) { // unsigned int 不可能小于0,无需判断>=0
        throw out_of_bounds();
    }
    return items[index];
}

// const版本:只读访问const对象的元素
const T& operator[](unsigned int index) const {
    if(index >= length) {
        throw out_of_bounds();
    }
    return items[index];
}

5. Matrix构造函数的内存泄漏

在matrix(int columns, int rows)构造函数里:

for(int i = 0; i< columns;i++) {
    tabs[i] = *new vektor<T>(rows);
}

这里new vektor<T>(rows)创建的临时对象,赋值给tabs[i]后就没人管了,会导致内存泄漏。其实不需要用new,直接赋值临时对象即可:

for(int i = 0; i< columns;i++) {
    tabs[i] = vektor<T>(rows);
}

额外的边界问题:selectedItem也越界了

你的menItems是4行(索引0-3),但selectedItem初始化为4,在print函数里i == selectedItem时,访问menItems[selectedTab][4]也会越界,记得把selectedItem改成0-3之间的值。

把这些问题逐一修复后,你的SIGSEGV错误应该就能解决了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:26:37