【问题标题】:Valgrind C: Argument of function has a fishy (possibly negative) valueValgrind C:函数参数具有可疑(可能为负)值
【发布时间】:2018-02-02 21:05:47
【问题描述】:

我在调用 malloc 或 realloc 的代码中的多个位置收到此错误消息。这是一个例子。

void* reallocate_array(void* ptr, size_t size)
{
    return realloc(ptr,size)
}

EDIT2:看起来问题出在测试用例中。我不能修改这个

char* reallocated = (char*) reallocate_array(allocated,-1)

这是我的解决方案,它摆脱了可疑的值错误

if((int)size < 0)
{
    return NULL;
}

我的印象是 size_t 是一个无符号整数,这意味着它永远不会是负数。这可能是 Valgrind 中的错误,还是警告我可能的环绕?

编辑:Valgrind 输出

==20841== 1 errors in context 1 of 3:
==20841== Argument 'size' of function realloc has a fishy (possibly negative) value: -1
==20841==    at 0x4C2BB78: realloc (vg_replace_malloc.c:785)
==20841==    by 0x4057B1: reallocate_array (allocation.c:24)
==20841==    by 0x402A8A: reallocate_NegativeBytes_Test::TestBody() (tests.cpp:56)

【问题讨论】:

  • 它说可能是负面的,鱼腥味可能意味着别的东西。此外,您应该改为显示呼叫。
  • 它闻到了一个可能由整数溢出(或其他错误)导致的可疑值,并让您知道。你最好检查一下。
  • 没有。这意味着您应该检查代码是否存在错误。 size 的任何值都是合法的。有些只是怀疑。
  • 这意味着您需要检查 reallocate_array 的调用位置,以查看传入的内容。
  • 在使用负值调用 reallocate_array 时是否收到警告,它声明为采用size_t - 即无符号

标签: c malloc valgrind


【解决方案1】:

对 Valgrind 的建议:将负实参传递给无符号类型的参数是非常正确的。在您的特定情况下,结果将是参数被转换为size_t 类型的最大可表示值,但这很可能与预期的不同。

我怀疑转换为一个大的正无符号值确实与您的测试用例的意图不同。由于测试用例预计内存分配失败,因此该案例可能通过了,但不是因为我怀疑其作者预期的原因。至少,这是一个糟糕的测试用例,因为不清楚它要测试什么。

至于您的解决方案,它也很可疑。该标准对您将(size_t) -1 转换为类型int 有这样的说法:

否则,新类型有符号,值无法表示 在里面;结果是实现定义的或 引发了实现定义的信号。

(C2011 6.3.1.3/3)

实现定义的行为和信号的可能性并不是一个舒适的地方。

如果你坚持验证函数内部的值,那么你可以考虑这个测试:

if (size & ~(SIZE_MAX >> 1)) {
    // ...
}

这测试是否设置了size 的最高有效位,如果该值是从不大于size_t 的任何负数转换而来的。

但是,我自己会尝试更改或删除测试用例。如果您愿意,可以使用 Valgrind 对此的抱怨来支持您的论点。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多