【发布时间】:2009-10-11 05:39:13
【问题描述】:
我有一个 C++ 单元测试,它产生有用的输出到 stderr,主要是噪音(除非我正在调试)到标准输出,所以我想将标准输出重定向到 /dev/null。
奇怪的是,这样做似乎会导致分段错误。
是否有任何原因导致代码可能会出现 "> /dev/null" 段错误并运行正常?
输出完全由printfs 产生,如果有任何影响的话。
我很难发布有问题的代码,因为它是提交发表的研究。我希望根据这个描述有一个“明显”的可能原因。
验尸
段错误是由如下代码引起的:
ArrayElt* array = AllocateArrayOfSize(array_size);
int index = GetIndex(..) % array_size;
ArrayElt elt = array[index];
我已经无数次忘记了,当x 在 C/C++ 中为负数时,x % y 仍然是负数。
好的,那为什么只有在我重定向到/dev/null 时才会发生这种情况?我的猜测是,我正在访问的无效内存地址位于 stdout 的输出缓冲区中 - 并且在不需要时不会分配此缓冲区。
感谢您的精彩回答!
【问题讨论】:
-
代码是多线程的吗?如果是这样,重定向标准输出可能会改变程序关键方面的时间并触发竞争条件错误。
-
不是多线程的。如何在输出重定向的进程上启动 gdb? "gdb ./mybinary > /dev/null" 也会重定向 gdb 的标准输出。
-
当任一操作数为负时,
x % y的符号是实现定义的,因此并不是说您不能可移植地依赖您所看到的行为。 -
@Tyler:如果您来自 LISP 领域或其他需要 (x mod y) 返回正数的地方,那么也许您应该为自己编写一个(模板?)函数来完成这项工作为您,并使用它来代替运营商?整数版本很简单;您可能需要为浮点数提供一种或多种特化。
标签: c++ redirect segmentation-fault stdout