防止C整数溢出

时间:2012-11-30 14:08:26

标签: c++ c linux

我在函数中有一些代码,它将使用递增/递减运算符更改/更新值。例如:

static void update_value(char op)
{
    if (op == '+')
        value++;    // uint32_t global value
    else
        value--;
}

该功能不会检查我们是否超过/低于最大/最小值。因此,当值为16时,调用者可以将其调用20次。结果为2 ^ 32 - 1 - 4。

我想提防,但我想使用标准库常量。我记得有一个size_t(或类似的)变量代表uint32_t可以容纳的最大数字。

我不记得确切的常量和定义它们的标题。有什么帮助吗?

7 个答案:

答案 0 :(得分:10)

在C中,您需要的头文件是<stdint.h>,常量是UINT32_MAX

static void update_value(char op)
{
    if (op == '+')
        if ( value < (UINT32_MAX - 1))
            value++;    // uint32_t global value
        else
            printf("too big!\n");
    else
       if (value > 0)
           value--;
       else
           printf("too small!\n");
}

对于C ++,您可以使用此处的任意数量的解决方案:What's the C++ equivalent of UINT32_MAX?

答案 1 :(得分:5)

我发现最常见的解决方案是检查递增的值是否实际上大于先前的值,或者递减的值是否小于先前的值。只有当值为无符号时,它才能,与变量的大小无关,并且几乎与C代码一样可移植。

static void update_value(char op)
{
  if (op == '+') {
    if (value + 1 > value) value ++;
  } else {
    if (value - 1 < value) value --;
  }
}

请注意,代码可能会使用签名值,但根据C标准,这将是未定义的行为,编译器可以if (value + 1 > value) ...替换为if (0) ... }。您应该将此代码与签名值一起使用,除非您有一个流程来审核生成的目标代码链接后

使用gcc和clang,您需要添加-fwrapv选项以使此代码适用于签名值;与其他编译器一样,您的里程可能会有所不同。

这样做的唯一理智方法是特定于类型并使用limits.h中的常量。例如:

#include "limits.h"

static void update_int(char op, int *value)
{
  int val = *value; // ignoring NULL pointer dereference

  if (op == '+') {
    if (val != INT_MAX) *value = val + 1;
  } else {
    if (val != INT_MIN) *value = val - 1;
  }
}

static void update_int(char op, unsigned int *value)
{
  unsigned int val = *value; // ignoring NULL pointer dereference

  if (op == '+') {
    if (val != UINT_MAX) *value = val + 1;
  } else {
    if (val != UINT_MIN) *value = val - 1;
  }
}

答案 2 :(得分:4)

也许您正在寻找<limits>http://www.cplusplus.com/reference/limits/numeric_limits/

你可以做这样的事情来得到你想要的东西:

unsigned int n = numeric_limits<unsigned int>::max()

您还拥有<cstdint>http://www.cplusplus.com/reference/cstdint/

UINTN_MAX:精确宽度无符号类型的最大值(精确2 ^ N-1)

答案 3 :(得分:2)

如果你正在使用C,那么你正在寻找limits.h。您想要的宏是UINT_MAX

如果你在C ++世界,你需要std::numeric_limits<uint32_t>::max()

答案 4 :(得分:2)

检查#include <stdint.h>http://en.wikipedia.org/wiki/C_data_types#Fixed_width_integer_types

您要找的是UINT32_MAX

答案 5 :(得分:0)

static void update_value(char op)
{
    if (op == '+')
        if (value == UINT_MAX)
            printf("Maximum value achieved.\n");
        else
            value ++;
    else
       if (value == 0)
           printf("Minimum value achieved.\n");
       else
           value --;
}

UINT_MAX,对于此常量,您必须包含limits.h

答案 6 :(得分:-1)

您需要limits.h(INT_MIN和INT_MAX):更多信息:http://www.cplusplus.com/reference/climits/