如何解决为什么从类调用 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
方法有很多 printf
和 cout
。但是,当我取消注释 main
中的行时,malloc
在第一个 print
或 cout
甚至 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);
请注意,上面的代码分配了一个设置为值 double
的 n
,当我认为您想要做的是分配一个包含 n 个双精度值的数组时。为此,您需要使用方括号而不是圆括号:
register double *cfs = new double[n];
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。