valgrind中的分段错误,但实际运行中没有

时间:2015-05-13 02:55:23

标签: c++ memory valgrind

我在Valgrind中运行时的代码会产生分段错误,但是在正常运行时却没有。这怎么可能?

valgrind指出的罪魁祸首:

static inline void * Vec_PtrEntry( Vec_Ptr_t * p, int i )
{
    assert( i >= 0 && i < p->nSize );
    return p->pArray[i];
}

来自valgrind的消息:

Process terminating with default action of signal 11 (SIGSEGV)
==3290==  Access not within mapped region at address 0x0

为什么会发生这种情况,通常代码运行完美?我该如何解决?我需要对代码进行一些内存分析。

1 个答案:

答案 0 :(得分:3)

如评论中所述,未定义的行为不必涉及崩溃。它可以很好地运作。但是,这似乎并非如此。

我们可以从消息中看到

Process terminating with default action of signal 11 (SIGSEGV)
==3290==  Access not within mapped region at address 0x0

程序试图访问地址0x0。这通常意味着我们已取消引用NULL指针。

查看您的代码:

static inline void * Vec_PtrEntry( Vec_Ptr_t * p, int i )
{
    assert( i >= 0 && i < p->nSize );
    return p->pArray[i];
}

我们可以看到您试图通过声明i>=0i<p->nSize来防范无效参数。但是,没有检查p本身是否有效。

您可以assert(p)确保它不是NULL。您应该在现有断言之前执行此操作。

至于为什么只在valgrind下运行时才会出现这种情况,一个重要的考虑因素是程序在valgrind下运行得慢得多,所以你可能暴露了一个问题,这个问题只发生在高负载下,或者至少是非常不同的动态行为。常态。

如何解决此问题并继续进行内存分析?你需要修复bug。

  1. 使用调试器。 gdb与valgrind完美结合
  2. 使用断言来验证p是非空的。
  3. 这些中的任何一个都应该允许您查看后向跟踪,并找出p为NULL的原因。