微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么从类调用 printf 时会出现分段错误?

如何解决为什么从类调用 printf 时会出现分段错误?

这是我的源代码的相关部分(我认为)

#include <iostream>
#include <cstdarg>
#include <cstring>
#include <cstdlib>



class poly
{
private:
    double *coefficients;
    size_t degree;
    inline double *cfp(size_t i);

public:
    poly();
    poly(size_t n,...);

    void Print() const;
    ~poly();
};

poly::poly()
{
    this->degree = 0;
    this->coefficients = new double(1);
    *(this->coefficients) = 1.;
}

poly::poly(size_t n,...)
{
    va_list coefs;
    va_start(coefs,n);

    this->degree = n;
    n++;
    register double *cfs = new double(n);
    this->coefficients = cfs;
    
    while (n--)
    {
        *cfs = va_arg(coefs,double);
        cfs++;
    }

    va_end(coefs);
}

void poly::Print() const
{
    bool started = false;
    double c = this->cf(0);
    putchar('a');
    std::cout << this->degree << '\n';
    if (c != 0.)
    {
        std::cout << c;
        started = true;
    }

    size_t N = this->degree;

    for (size_t i = 1; i <= N; i++)
    {
        c = this->cf(i);
        if (c != 0.)
        {
            if (!started)
                started = true;
            else
                std::cout << ((c < 0.) ? " - " : " + ");
                //printf(" + ");
            std::cout << fabs(c) << " x^" << i;
            //printf("%lf x^%lu",c,i);
        }
    }
    printf("\n");
}


poly::~poly()
{
    delete this->coefficients;
}

int main()
{
    //printf("\n");        <- Uncommenting this line stops the error
    poly p1(7,1.,3.,-9.,2.,0.,8.,-2.,6.);
    p1.Print();
}


现在,Print 方法有很多 printfcout。但是,当我取消注释 main 中的行时,malloc 在第一个 printcout 甚至 putchar 来自 'Print` 方法时带来分段错误。我在那里找不到任何内存泄漏。为什么会发生,如何预防?

我在 WSL Ubuntu 上使用 gcc (g++) 9.3.0。该程序使用标志 -lc -g 编译。

gdb 给我看了这个

malloc(): corrupted top size

Program received signal SIGABRT,Aborted.
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
50      ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) backtrace 
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1  0x00007ffff7c0f859 in __GI_abort () at abort.c:79
#2  0x00007ffff7c7a3ee in __libc_message (action=action@entry=do_abort,fmt=fmt@entry=0x7ffff7da4285 "%s\n")
    at ../sysdeps/posix/libc_fatal.c:155
#3  0x00007ffff7c8247c in malloc_printerr (str=str@entry=0x7ffff7da2556 "malloc(): corrupted top size") at malloc.c:5347
#4  0x00007ffff7c8583a in _int_malloc (av=av@entry=0x7ffff7dd5b80 <main_arena>,bytes=bytes@entry=1024) at malloc.c:4107
#5  0x00007ffff7c872d4 in __GI___libc_malloc (bytes=1024) at malloc.c:3058
#6  0x00007ffff7c6ee84 in __GI__IO_file_doallocate (fp=0x7ffff7dd66a0 <_IO_2_1_stdout_>) at filedoalloc.c:101
#7  0x00007ffff7c7f050 in __GI__IO_doallocbuf (fp=fp@entry=0x7ffff7dd66a0 <_IO_2_1_stdout_>) at libioP.h:948
#8  0x00007ffff7c7e0b0 in _IO_new_file_overflow (f=0x7ffff7dd66a0 <_IO_2_1_stdout_>,ch=97) at fileops.c:745
--Type <RET> for more,q to quit,c to continue without paging--
#9  0x00007ffff7c73482 in putchar (c=97) at putchar.c:28
#10 0x0000555555555cfe in poly::Print (this=0x7fffffffdb90) at polynomial_r.cpp:241
#11 0x0000555555555fd2 in main () at test.cpp:7
(gdb) info frame
Stack level 0,frame at 0x7fffffffd6f0:
 rip = 0x7ffff7c3018b in __GI_raise (../sysdeps/unix/sysv/linux/raise.c:50); saved rip = 0x7ffff7c0f859
 called by frame at 0x7fffffffd820
 source language c.
 Arglist at 0x7fffffffd5c8,args: sig=sig@entry=6
 Locals at 0x7fffffffd5c8,PrevIoUs frame's sp is 0x7fffffffd6f0
 Saved registers:
  rip at 0x7fffffffd6e8
(gdb) 

解决方法

看起来您通过写入超过堆分配的末尾而损坏了堆。我认为你的问题在这里:

register double *cfs = new double(n);

请注意,上面的代码分配了一个设置为值 doublen,当我认为您想要做的是分配一个包含 n 个双精度值的数组时。为此,您需要使用方括号而不是圆括号:

register double *cfs = new double[n];

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?