1

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

PS对不起,如果我的问题很愚蠢,但我搜索了这个主题并没有找到任何关于这个主题的合理文章。感谢您的所有意见。

4

2 回答 2

3

分段错误的主要来源是

  • 未初始化的指针(或一般未初始化的变量)
  • 对数组的越界访问
  • 编码不良的指针算法

处理此问题的主要策略包括:

  • 始终初始化变量,尤其是指针
  • 避免裸指针(更喜欢智能指针,例如std::unique_ptrstd::shared_ptr用于拥有数据的指针,如果您只想指向东西,则在标准容器中使用迭代器)
  • 使用标准容器(例如std::vector)而不是数组和指针算法

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

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

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

于 2013-05-27T07:49:39.690 回答
2

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

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

您只需要两个线程都将 p 视为非 null,被抢占以拥有 SIGSEV 场景。正如@jogojapan 指出的那样,使用标准容器或智能指针可以缓解这个问题。

于 2013-05-27T08:00:32.823 回答