如何检测通过错误大小的空c数组
How To detect an empty C-array passed with wrong size?
我有一个binarysearch函数,接口如下:
bool binarysearch(int* array, int size, int findnum) {
doBinarySearch(array, 0, (size-1), findnum);
}
doBinarySearch的代码是:
bool doBinarySearch(int* array, int start, int end, int findnum) {
if (end <= start)
return false;
int mid = (start+end)/2;
if (array[mid] == findnum) {
return true;
} else if (findnum < array[mid]) {
return doBinarySearch(array, start, mid, findnum);
} else {
return doBinarySearch(array, mid+1, end, findnum);
}
}
我写了一个单元测试来测试上面的函数。如果我调用binarysearch与空数组和错误的大小从main,代码段。意料之中的故障。例如int main() {
int *array;
binarysearch(array, 10, -1);
}
但是如果我写一个单元测试类,并有一个函数来完成上面的工作,那么二进制搜索就不会崩溃。知道为什么会有不同的行为吗?
class TestBinarySearch {
public:
void testEmptyArray() {
int *array;
binarysearch(array, 10, -1);
}
};
int main() {
TestBinarySearch testObj;
// below line does not cause seg fault. and -1 is found for some reason
testObj.testEmptyArray();
}
另一个问题-是否有任何方法来检测seg。如果有人调用了错误大小的函数?我看到一些使用信号捕获的例子,但在那之后,除了退出程序,还能做什么?
两种写法都会调用未定义行为。未定义行为可以是任何。它坠落在一个你应该感激的地方;不幸的是,它在另一方面"成功"了,但这是很有可能的。下次重启电脑或运行程序时,这种行为甚至可能会改变,谁知道呢。这是未定义的。
如果你用的是Linux,在valgrind下运行这两个程序,看看它说什么。即使没有崩溃,它也可能报告错误。
读取超出数组末尾是未定义的行为,正如John所说。编译器可以做任何它喜欢的事;你的软件可能会崩溃,可能会处理垃圾数据,可能会重新格式化你的硬盘(至少在标准一致性方面)。
没有办法检测给定的数组大小是否错误。
解决这个问题的正确方法是传入一个STL容器而不是一个C数组。至少,您可以这样重写binarySearch
函数:
bool binarysearch(std::vector<int> array, int findnum) {
doBinarySearch(&array[0], 0, array.size()-1, findnum);
}
这种情况不是一个空数组,这是一个单化的指针变量。对未初始化指针的解引用是未定义行为。这是一个程序错误,你不能防止它。
未定义行为意味着任何事情都可能发生。崩溃一次,别再崩溃了,一切都在意料之中。
有了这个API,你的调用者和你的单元测试必须确保传入的数组是有效的,并且至少与传入的长度一样长,并且绝对没有办法通过编程检查这是如此。
你可以考虑将API改为使用STL集合,但那将是另一个问题。
顺便说一句,你有一个不相关的错误。代码应该是:
if (end < start) return false;
- 类动态数组错误
- 如何返回多维数组?错误C2440
- 数组错误(不允许类型不完整)
- C++ 将文件读取到数组错误:'operator>>'不匹配
- 不断增加的指针数组 错误:赋值中的类型不兼容
- 从文本文件读取 2D 数组错误
- 动态结构数组错误
- 旋转数组 - 错误
- 按字母顺序排序名称,数组错误
- 因为每个循环都读取数组错误
- 二维数组错误
- C 获取数组错误
- 编译时出现字符串数组错误
- c++2维指针类数组错误(使用openframework)
- C++数组错误
- C++上数组错误的大小
- C++数组错误:访问冲突读取位置0xC0000005
- c++2D数组错误
- C++:为“char [4]”数组错误获取太多初始值设定项
- 分段错误(核心转储)排序字符串数组错误