简体   繁体   English

为什么一个段出现故障而另一个没有?

[英]Why is one seg faulting and the other not?

Hi I have a program that needs to compare a string array to a predefined string but when I use the variable args[0] it works in my function strcmp as below嗨,我有一个程序需要将字符串数组与预定义的字符串进行比较,但是当我使用变量 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);
}

However when trying to strcmp args[i] such as below I get a seg fault.但是,当尝试 strcmp args[i] 如下所示时,我遇到了段错误。 Can anyone help me find a solution to this problem?谁能帮我找到解决这个问题的方法?

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[] is an array of strings that were previously separated by spaces, this program is for a custom shell, so pretend in my shell command line I input "cat echo ls" args[0] would be "cat" and so on. args[] 是一个以前用空格分隔的字符串数组,这个程序用于自定义 shell,所以假设在我的 shell 命令行中我输入“cat echo ls” args[0] 将是“cat”等等。 However now I need to implement i/o redirection.但是现在我需要实现 i/o 重定向。 So i need to check every element of args to check if they represent the symbols "<" ">" "|"所以我需要检查 args 的每个元素来检查它们是否代表符号 "<" ">" "|" and if one of them is we can take it from there如果其中之一是我们可以从那里拿走

Without seeing all the code, or a report from a tool such as valgrind , I can't say for sure.没有看到所有代码,或来自valgrind等工具的报告,我不能肯定地说。 But I can tell you that this loop is full of potential problems.但是我可以告诉你,这个循环充满了潜在的问题。

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

It's iterating through three arrays ( args , functions , and function_address ) based on some function call which takes none of those as variables ( gash_command_num() ) which has an unknown relation to how many elements are actually in those arrays.它基于某个函数调用迭代三个数组( argsfunctionsfunction_address ),这些函数调用不将这些作为变量( gash_command_num() ),这些变量与这些数组中实际有多少元素具有未知关系。

And it's using two global variables ( functions and function_addresses ) which could contain anything.它使用了两个可以包含任何内容的全局变量( functionsfunction_addresses )。

If all those things are related, I would suggest making that explicit... but I suspect they're not.如果所有这些事情都是相关的,我会建议明确说明......但我怀疑它们不是。 I suspect your loop logic is wrong.我怀疑你的循环逻辑是错误的。 It's comparing args[i] with functions[i] .它正在比较args[i]functions[i] I suspect gash_command_num() is actually the size of functions and so the loop is walking off args .我怀疑gash_command_num()实际上是functions的大小,因此循环正在脱离args

What I suspect you really want to do is to see if args[0] matches any function name in functions and then call the related function .我怀疑你真正想要做的是看是否args[0]在匹配任何函数名functions ,然后调用相关功能 If args[0] is ls then you want to check if there's a built in shell function for ls and call it with all the arguments.如果args[0]ls那么您要检查是否有ls的内置 shell 函数并使用所有参数调用它。

Rather than searching a list over and over again, and having to manage two parallel lists, this would be much better served with a hash table .与其一遍又一遍地搜索列表,并且必须管理两个并行列表,不如使用哈希表来提供更好的服务。 The keys are the function names, the values are the function pointers.键是函数名,值是函数指针。 C doesn't have a hash table built in, but there's plenty of libraries for that. C 没有内置的哈希表,但有很多库。 Gnome Lib is a solid choice for this and many other basic functionality that C is missing. Gnome Lib是 C 缺少的许多其他基本功能的可靠选择。

Using a hash table, and eliminating the globals, your code reduces to this:使用哈希表并消除全局变量,您的代码简化为:

/* 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);
    }
}

Scanning for pipes is now a separate problem.扫描管道现在是一个单独的问题。 For that you do want to loop through args looking for special characters.为此,您确实希望遍历args查找特殊字符。 That is made much simpler if, when you create args , you ensure it ends with a null pointer.如果在创建args时确保它以空指针结尾,这args得更简单。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM