在这个方法中,我想查看单词搜索中是否出现一个字符串。由于字符串可以出现在任何方向,因此我使用以下方法检查这些方向:
目前我的代码在运行时会出现分段错误。发生这种情况是因为我的方法中的第一个if语句是根据gdb跳过的。
我正在使用的网格如下所示:
a r e o
o n l y
o d d a
运行时(就在segfault之前)的x,y和str的值是:
x = 0;
y = 0;
str = "add"
现在,strlen(str)的计算结果为3,x - 3
的计算结果为-3。
-3 < 0
会评估为true并退出我的方法。不幸的是,在运行时跳过方法开头的if语句。有谁知道发生了什么?
此外,如果我将网格的第一行更改为:
,我将添加q r e o
我得到了正确的结果。
以下是方法:
bool checkNorth (int x, int y, string str) {
//Deal with trival case and avoid array out of bounds/checking silly things
if (x-strlen(str) < 0){
return false;
}
//for each character in str
for (int i = 0; i < (strlen(str)); i++){
//If the character above in the grid is the next character in the string
if (grid[x-i][y].letter == str[i]){
//keep going
continue;
}else{
//It ain't north
return false;
}
}
//It's north
return true;
}
答案 0 :(得分:8)
由于strlen()
返回类型为size_t
且未签名的值,因此您计算x - 3
计算是在无符号值上完成的,而使用无符号算术0 - 3
是一个很大的正值,并且永远不会小于零。事实上,由于比较是针对小于0的无符号数量,但无符号数量永远不会是负数,编译器可以完全优化整个if
测试和以下return
。
您可以通过更改以下内容来解决问题:
if (x-strlen(str) < 0){
为:
if (x < strlen(str)) {
请注意,你的循环效率有点低。你有:
for (int i = 0; i < (strlen(str)); i++){
这会在每次迭代时重新计算strlen(str)
。你可以写:
size_t len = strlen(str);
for (size_t i = 0; i < len; i++) {
这保证长度只计算一次,这是足够的,除非你在函数的某个地方修改字符串,或者它调用的函数之一。