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

C++类成员函数调用printf/cout时触发段错误的原因是什么?

问题根本原因

你遇到的堆破坏错误和混用printf/cout没有任何关系,是堆内存越界写导致的,问题出在内存分配的语法写错了:

  1. C++中,new double(n)的含义是分配1个double类型的内存空间,并将其初始化为值n,而非分配长度为n的double数组。分配数组的正确语法是new double[n](方括号而非圆括号)。
  2. 你的带参构造函数中,传入的degree是7,随后你执行了n++得到8,然后用new double(n)仅分配了1个double的空间,后续循环往这个地址写入8个double值,直接越界改写了堆上的元数据,当后续putchar/cout需要调用malloc分配stdout缓冲区时,就会检测到堆结构损坏,触发崩溃。
  3. 取消printf("\n")的注释后崩溃消失属于未定义行为的随机表现:这行printf会提前触发stdout缓冲区的分配,你越界写的堆空间刚好踩在了已经分配的缓冲区上,没有破坏malloc的核心元数据,因此暂时隐藏了问题,但内存越界的bug依然存在。

另外你代码里还有两个关联错误:

  • 你在Print方法中调用了this->cf(0),但类定义中只声明了cfp方法,没有声明cf,属于粘贴遗漏或者定义缺失。
  • 如果你分配的是数组,释放内存必须用delete[],而非delete,你当前的析构函数用delete释放数组也会导致未定义行为。

修复方案

快速修复写法

修改构造函数和析构函数的内存操作:

// 默认构造函数
Poly::Poly()
{
    this->degree = 0;
    // 分配长度为1的数组,用方括号
    this->coefficients = new double[1];
    this->coefficients[0] = 1.;
}

// 带参构造函数
Poly::Poly(size_t n, ...)
{
    va_list coefs;
    va_start(coefs, n);

    this->degree = n;
    size_t count = n + 1;
    // 分配数组用方括号
    double *cfs = new double[count];
    this->coefficients = cfs;
    
    for (size_t i = 0; i < count; i++)
    {
        cfs[i] = va_arg(coefs, double);
    }

    va_end(coefs);
}

// 析构函数
Poly::~Poly()
{
    // 释放数组用delete[]
    delete[] this->coefficients;
}

更安全的推荐写法

抛弃裸指针和可变参数,用C++标准容器管理内存:

#include <vector>
#include <initializer_list>

class Poly
{
private:
    std::vector<double> coefficients;
    size_t degree;
public:
    Poly() : degree(0), coefficients{1.} {}
    // 用initializer_list传系数,无需处理可变参数
    Poly(size_t n, std::initializer_list<double> coefs) : degree(n), coefficients(coefs) {}
    
    void Print() const {
        // 直接用coefficients[i]访问即可,不需要自己实现内存管理
    }
    // 不需要手动写析构函数,vector自动释放内存
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.13 02:12:04