如何避免SIGSEGV?

时间:2013-05-27 07:42:10

标签: c++ sigsegv

我正在编写一个客户端 - 服务器守护程序,它必须接受并转换特定的消息格式,检查它们是否提交以将所有活动提交给DB。程序是多线程的。所以,我开始工作,并在某些情况下开始获得SIGSEGV。所以我不得不重新设计我的程序并重新开始。 我想知道,如果有任何“最佳实践”或提示如何最大限度地降低SIGSEGV的风险? 我知道,每个指针都应在使用前检查,删除后应为NULLED,但如果有任何高级别,设计提示?

P.S。对不起,如果我的问题非常假,但我搜索了这个主题,并没有找到任何关于这个主题的合理文章。您的所有意见都表示赞赏。

2 个答案:

答案 0 :(得分:2)

分段错误的主要来源是

  • 未初始化的指针(或一般未初始化的变量)
  • 对阵列的越界访问
  • 编码不佳的指针算术

解决这个问题的主要策略包括:

  • 始终初始化变量,特别是指针
  • 避免使用裸指针(对于拥有数据的指针,更喜欢智能指针,如std::unique_ptrstd::shared_ptr,如果只想指向,请使用迭代器到标准容器中的东西)
  • 使用标准容器(例如std::vector)代替数组和指针算术

正如评论中所提到的,编码不良的并发或并行化可能导致分段错误(以及许多其他问题),其方式与未初始化的变量类似,因为它们可能会导致变量的值意外更改。处理这个问题的一般策略包括:

  • 避免使用共享数据 - 更喜欢使用消息传递/队列进行线程间通信
  • 如果您有共享数据,并且至少有一个线程写入这些数据,请使用互斥锁,std::atomic或类似的保护

但是,在某些情况下,两者都可能意味着您会失去显着的性能优势。正确地获得并行算法是一个仔细分析和设计的问题。

答案 1 :(得分:2)

并发可能是许多问题的根源,有几种不同的方式,而SIGSEV是其中一个问题。 初学者可能会将指针Data* p;传递给两个线程,在退出之前让它们执行此代码。

if(p){
 delete p->data;
 delete p;
 p = NULL;
}

你只需要两个线程将p视为非null,就可以抢占SIGSEV场景。使用@jogojapan指出的标准容器或智能指针可以缓解这个问题。