C++ SIGABRT和SIGSEGV之间有什么区别

C++ SIGABRT和SIGSEGV之间有什么区别,c++,linux,signals,coredump,C++,Linux,Signals,Coredump,我用下面两段代码犯了核心转储错误: //test.cpp int main() { int *p = new int; *p = 100; delete p; delete p; return 0; } //test2.cpp int main() { int *p = new int; *p = 100; delete p; *p = 111; std::cout<<*p<<std::en

我用下面两段代码犯了核心转储错误:

//test.cpp
int main()
{
    int *p = new int;
    *p = 100;
    delete p;
    delete p;
    return 0;
}

//test2.cpp
int main()
{
    int *p = new int;
    *p = 100;
    delete p;
    *p = 111;
    std::cout<<*p<<std::endl;
    return 0;
}
//test.cpp
int main()
{
int*p=新的int;
*p=100;
删除p;
删除p;
返回0;
}
//test2.cpp
int main()
{
int*p=新的int;
*p=100;
删除p;
*p=111;

STD::CUT< P>这两个例子都是未定义的行为,这意味着根据C++,编译器(和系统)可以做任何想做的事情。
  • 在情况1中,可能会检查指针的双重删除,因此会发出
    SIGABRT
    信号。
    SIGABRT
    表示异常终止条件,例如由abort()启动
  • 在案例2中,系统检测到您对已删除指针的遵从性,并 创建
    SIGSEGV
    信号。
    SIGSEGV
    表示内存访问无效(分段故障)

但两者都是UB,因此这只是当前编译器/os/系统的一个功能。从错误的定义来看,错误之间的区别很明显。一个是中止,通常由编译器或编码器生成。另一个是由无效的内存访问引起的,通常由操作系统或硬件发出信号。

删除指针twice是未定义的行为,这意味着任何事情都可能发生。在这种情况下,它会导致发出
SIGABRT
信号

访问不属于程序的内存也是未定义的行为,在这种情况下会导致分段错误,并发出
SIGSEGV

  • SIGABRT
    表示程序本身检测到并通过调用报告的错误
  • SIGSEGV
    表示对有效内存的访问无效

通过执行delete(其检测到第二次删除无效)显式检测SIGABRT并发出信号。通过调用abort函数启动SIGABRT

SIGSEGV不同,它正在进行检查,而不是像以前一样通过库中的检查检测到,它是通过操作系统的内存管理启动的


请参见

这里列出了各种信号的含义:该问题中没有C。请在以后的问题中选择标记时更加小心。这两个代码段都有未定义的行为,可能会导致任何这些信号,或者根本没有。因此,它们不会演示anything@VTT通过讨论为什么每个都是UB,这将是一个问题回答得很好。关于为什么每个都是UB的解释可以在老问题中找到,它与这个问题的标题无关。这并不能解释SIGABRT和SIGSEGV之间的区别either@VTT谢谢你的提示。我看到你复制了第一条评论中的链接,但剩下的答案只是试图解释一下UB@VTT所有的dif检测中的引用mode@VTT不要只是批评,请给出你的答案,让我们大家都知道什么是真正的答案;-)@bruno建设性的批评是好的。我相信VTT是在帮助你回答问题,而不是伤害你的答案…@FantasticMrFox是的,当然,我是讽刺。但你自己要小心不要用批评伤害他他的名字写得不好,他是VTT而不是CTT(这是一个笑话,你们两个都不要那么糟糕^^)。哦,你们纠正了