为什么一个是断层而另一个不是?

时间:2016-04-19 22:18:17

标签: c segmentation-fault

您好我有一个程序需要将字符串数组与预定义字符串进行比较但是当我使用变量args [0]时,它在我的函数strcmp中工作如下

int gash_execute(char **args){
    int i;

    if(args[0] == NULL){
        return 1;
    }

    for(i = 0; i < gash_command_num(); i++){
        if(strcmp(args[0], functions[i]) == 0){
            return(*function_address[i])(args);     
        } 
    }
    return gash_launch(args);
}

然而,当试图strcmp args [i]如下面我得到一个seg错误。任何人都可以帮我找到解决这个问题的方法吗?

int gash_execute(char **args){
    int i;

    if(args[0] == NULL){
        return 1;
    }

    for(i = 0; i < gash_command_num(); i++){
        if(strcmp(args[i], functions[i]) == 0){
            return(*function_address[i])(args);     
        } 
    }
    return gash_launch(args);
}

args []是一个以前用空格分隔的字符串数组,这个程序用于自定义shell,所以假装在我的shell命令行中我输入“cat echo ls”args [0]将是“cat”并且等等。但是现在我需要实现i / o重定向。所以我需要检查args的每个元素以检查它们是否代表符号“&lt;” “&gt;” 中“|”如果其中一个是我们可以从那里拿走它

1 个答案:

答案 0 :(得分:1)

如果没有看到所有代码或来自valgrind等工具的报告,我无法肯定地说。但我可以告诉你,这个循环充满了潜在的问题。

for(i = 0; i < gash_command_num(); i++){
    if(strcmp(args[i], functions[i]) == 0){
        return(*function_address[i])(args);     
    } 
}

它基于一些函数调用迭代三个数组(argsfunctionsfunction_address),这些函数调用不会将这些数组作为变量(gash_command_num())与这些数组中实际有多少元素的未知关系。

它使用两个全局变量(functionsfunction_addresses),它们可以包含任何内容。

如果所有这些事情都有关系,我建议明确说明......但我怀疑他们不是。我怀疑你的循环逻辑是错误的。它将args[i]functions[i]进行比较。我怀疑gash_command_num()实际上是functions的大小,因此循环走了args

我怀疑你真正想要做的是看args[0]是否匹配functions中的任何函数名称,然后调用相关函数 。如果args[0]ls,那么您要检查ls是否有内置shell函数,并使用所有参数调用它。

不是一遍又一遍地搜索列表,而是必须管理两个并行列表,而使用hash table会更好。键是函数名,值是函数指针。 C没有内置的哈希表,但是有很多库。 Gnome Lib是这个以及C缺少的许多其他基本功能的坚实选择。

使用哈希表并消除全局变量,您的代码将减少到:

/* For encapsulation */
typedef int(*shell_function_t)(char **);

int gash_execute(char **args, GHashTable *shell_functions){
    int i;

    if(args[0] == NULL){
        return 1;
    }

    shell_function_t func = g_hash_table_lookup(shell_functions, args[0]);
    if( func ) {
        return(*func)(args);
    }
    else {
        return gash_launch(args);
    }
}

扫描管道现在是一个单独的问题。为此你想要遍历args寻找特殊字符。如果在创建args时确保它以空指针结束,那么这就变得更加简单了。

for(int i = 0; args[i] != NULL; i++) {
    ...check if args[i] is special...
}