一尘不染

C:处理大量数字时避免溢出

linux

我已经在C中实现了一些排序算法(用于对整数进行排序),并谨慎地uint64_t用于存储与数据大小有关的任何内容(因此还包括了计数器和填充物),因为该算法也应使用数千兆字节的数据集进行测试整数

这些算法应该很好,并且分配的数据量应该没有问题:数据存储在文件中,并且每次仅加载很少的块,即使将内存中的缓冲区阻塞为任意大小,也可以正常工作。

使用数据集最多4千兆字节(因此16GB数据)的测试可以正常工作(排序4Gint花了2228秒,约37分钟),但是当我们超过该值(即:8
Gints)时,该算法似乎没有停止(这是现在已经运行了大约16个小时)。

恐怕问题可能是由于整数溢出造成的,可能是循环中的计数器存储在32位变量上,或者也许我们正在调用一些可用于32位整数的函数。
还有什么呢?

有什么简单的方法可以检查运行时是否发生整数溢出?


阅读 233

收藏
2020-06-07

共1个答案

一尘不染

这是特定于编译器的,但是如果您使用的是gcc,则可以在发生有符号积分溢出时进行编译-ftrapv以发出问题SIGABRT

例如:

/* compile with gcc -ftrapv <filename> */
#include <signal.h>
#include <stdio.h>
#include <limits.h>

void signalHandler(int sig) {
  printf("Overflow detected\n");
}

int main() {
  signal(SIGABRT, &signalHandler);

  int largeInt = INT_MAX;
  int normalInt = 42;
  int overflowInt = largeInt + normalInt;  /* should cause overflow */

  /* if compiling with -ftrapv, we shouldn't get here */
  return 0;
}

当我在本地运行此代码时,输​​出为

Overflow detected
Aborted
2020-06-07