【问题标题】:Segmentation fault in simple path finding Code简单寻路代码中的分段错误
【发布时间】:2017-09-12 18:02:24
【问题描述】:

我一直在尝试调试此代码,但现在确实需要帮助。这是在网格中查找字符串的代码,但由于某种原因,我遇到了分段错误。任何指针都将受到高度赞赏

#include <stdio.h>

char grid[5][5] = {
    {'t', 'z', 'x', 'c', 'd'},
    {'a', 'h', 'n', 'z', 'x'},
    {'h', 'w', 'o', 'i', 'o'},
    {'o', 'r', 'n', 'r', 'n'},
    {'a', 'b', 'r', 'i', 'n'},
};
int n = 5;
int found = 0; // flag indicating if string has been found


void find(int i, int j, char *search) {
    if (i >= n || j >= n || i < 0 || j < 0) {
        return ;
    }

    if (!search) {
        found = 1;
        return ;
    }

    if (grid[i][j] == search[0]) {

        find (i+1, j, search+1); 
        find (i, j+1, search+1);
        find (i+1, j+1, search+1);
        find (i-1, j, search+1);
        find (i, j-1, search+1);
        find (i-1, j-1, search+1);
    }
    else {
        find (i+1, j, search); 
        find (i, j+1, search);
        find (i+1, j+1, search);
        find (i-1, j, search);
        find (i, j-1, search);
        find (i-1, j-1, search);
    }
}


int main() {
    char s[] = {'h', 'o', 'r', 'i', 'z', 'o', 'n', '\0'}; // String to be searched
    find(0, 0, s);
    printf("%s\n", found ? "Found": "Not Found");    
    return 0;
}

【问题讨论】:

  • 我没有分析你的代码将运行的每一步。但我认为你应该在使用之前检查“搜索”的范围。希望对你有帮助
  • 使用c++编码时,检查数组的每个范围是一个好习惯
  • 如果“检查范围”是指索引在grid 范围内,那么他确实 这样做了。
  • 您需要缓存一些值,我相信您的递归会一次又一次地评估相同的值。尝试使用动态编程来解决这个问题。
  • 另外(grid[I][j] == search[0]) 的else 似乎不正确。如果您正在寻找一条连续的路径,则如果字符不匹配,则不应尝试搜索邻居。

标签: c debugging path segmentation-fault backtracking


【解决方案1】:

你的问题是堆栈溢出。

如果您在调试器下运行程序,您会看到如下内容:

Program received signal SIGSEGV, Segmentation fault.
0x00000000004006d5 in find (i=3, j=4, search=0x7fffffffdd44 "zon") at t.c:34
34          find (i+1, j, search);
(gdb) bt 10
#0  0x00000000004006d5 in find (i=3, j=4, search=0x7fffffffdd44 "zon") at t.c:34
#1  0x0000000000400720 in find (i=4, j=4, search=0x7fffffffdd44 "zon") at t.c:37
#2  0x00000000004006da in find (i=3, j=4, search=0x7fffffffdd44 "zon") at t.c:34
#3  0x0000000000400720 in find (i=4, j=4, search=0x7fffffffdd44 "zon") at t.c:37
#4  0x00000000004006da in find (i=3, j=4, search=0x7fffffffdd44 "zon") at t.c:34
#5  0x0000000000400720 in find (i=4, j=4, search=0x7fffffffdd44 "zon") at t.c:37
#6  0x00000000004006da in find (i=3, j=4, search=0x7fffffffdd44 "zon") at t.c:34
#7  0x0000000000400720 in find (i=4, j=4, search=0x7fffffffdd44 "zon") at t.c:37
#8  0x00000000004006da in find (i=3, j=4, search=0x7fffffffdd44 "zon") at t.c:34
#9  0x0000000000400720 in find (i=4, j=4, search=0x7fffffffdd44 "zon") at t.c:37
#10 0x00000000004006da in find (i=3, j=4, search=0x7fffffffdd44 "zon") at t.c:34
(More stack frames follow...)

请注意,索引是重复的,您并没有取得进展。还有这个:

(gdb) bt -10
#261985 0x0000000000400720 in find (i=4, j=4, search=0x7fffffffdd44 "zon") at t.c:37
#261986 0x0000000000400651 in find (i=4, j=3, search=0x7fffffffdd43 "izon") at t.c:27
#261987 0x0000000000400651 in find (i=4, j=2, search=0x7fffffffdd42 "rizon") at t.c:27
#261988 0x00000000004006f0 in find (i=4, j=1, search=0x7fffffffdd42 "rizon") at t.c:35
#261989 0x00000000004006f0 in find (i=4, j=0, search=0x7fffffffdd42 "rizon") at t.c:35
#261990 0x0000000000400637 in find (i=3, j=0, search=0x7fffffffdd41 "orizon") at t.c:26
#261991 0x0000000000400637 in find (i=2, j=0, search=0x7fffffffdd40 "horizon") at t.c:26
#261992 0x00000000004006da in find (i=1, j=0, search=0x7fffffffdd40 "horizon") at t.c:34
#261993 0x00000000004006da in find (i=0, j=0, search=0x7fffffffdd40 "horizon") at t.c:34
#261994 0x000000000040079f in main () at t.c:46

告诉您,在程序因堆栈耗尽而崩溃之前,它成功地(递归地)调用了 find 260,000 多次。

【讨论】:

    【解决方案2】:

    您的实现的问题是您没有正确编写递归。对于连续路径搜索,如果字符不匹配,则不应查看邻居。

    您犯的第二个错误是期望search 在字符串完成时变为NULL。事实上你需要检查search[0] =='\0'。

    由于你不看邻居(通过删除else),你需要查看所有起点。

    考虑下面的代码。

    #include <stdio.h>
    
    char grid[5][5] = {
        {'t', 'z', 'x', 'c', 'd'},
        {'a', 'h', 'n', 'z', 'x'},
        {'h', 'w', 'o', 'i', 'o'},
        {'o', 'r', 'n', 'r', 'n'},
        {'a', 'b', 'r', 'i', 'n'},
    };
    int n = 5;
    int found = 0; // flag indicating if string has been found
    void find(int i, int j, char *search) {
         if (i >= n || j >= n || i < 0 || j < 0) {
             return ;
         }
    
         if (search[0]=='\0') {
             found = 1;
             return ;
         }
    
         if (grid[i][j] == search[0]) {
             find (i+1, j, search+1); 
             find (i, j+1, search+1);
             find (i+1, j+1, search+1);
             find (i-1, j, search+1);
             find (i, j-1, search+1);
             find (i-1, j-1, search+1);
         }
    }
    
    
    int main() {
         char s[] = {'h', 'o', 'r', 'i', 'z', 'o', 'n', '\0'}; // String to be searched
         int i, j;
         for(i = 0; i<n && !found;i++)
             for(j = 0; j<n && !found;j++){
                 find(i, j, s);
             }
         printf("%s\n", found ? "Found": "Not Found");    
         return 0;
    }
    

    这可以正常工作并打印Found。

    在这里演示:https://ideone.com/l3ohwr

    【讨论】:

    • 谢谢..按预期工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-19
    • 1970-01-01
    • 2020-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多