我使用上面的两段代码使核心转储错误:
//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;
}
Gdb告诉我,由于信号SIGABRT,第一部分代码被核心转储,而由于信号SIGSEGV,第二部分代码被核心转储。
您能告诉我们有什么区别吗?
答案 0 :(得分:3)
删除的实现明确检测并通知了SIGABRT,检测到第二个删除的无效性。通过调用 abort 函数
启动SIGSEGV与众不同,它正在进行中,而不是像以前的库中的检查所检测到的那样,而是通过操作系统的内存管理启动的
答案 1 :(得分:2)
这两个示例都是未定义的行为,这意味着根据c ++,编译器(和系统)可以执行所需的任何操作。
SIGABRT
信号。 SIGABRT
表示异常终止条件,例如由abort()启动。SIGSEGV
信号。 SIGSEGV
表示无效的内存访问(分段错误) 但是两者仍然是UB,因此这只是当前编译器/操作系统/系统的功能。从错误here的定义中可以明显看出错误之间的区别。一种是中止,通常由编译器或编码器生成。原因之一是无效的内存访问,通常是由操作系统或硬件发出的信号。
答案 2 :(得分:2)
两次删除指针是未定义的行为,这意味着任何事情都可能发生。在这种情况下,会导致发出SIGABRT
信号。
访问不属于程序的内存也是未定义的行为,在这种情况下会导致分段错误并发出SIGSEGV
。
SIGABRT
表示程序本身检测到并通过调用abort
报告的错误。SIGSEGV
表示对有效内存的无效访问。