【问题标题】:Blank Line Seg. Fault (Writing Own Shell)空行段。错误(编写自己的外壳)
【发布时间】:2015-11-13 06:41:48
【问题描述】:

我还在学习编写简单的 shell。

我希望这个 shell 允许空行和 cmets。

我做了一些编码,遇到了一个问题,如果我直接输入enter(空白行),它会直接seg.fault core dumped。

我不知道到底哪里出错了,因为我打印了所有内容,一切看起来都很好。我在这行中唯一怀疑的事情

if (args[0] == NULL || !(strncmp(args[0],"#",1))) {
    exitstat = 0;
}

我从基本的 split 命令函数中得到了参数。奇怪的是 cmets 工作得很好。

下面是我的函数,用于读取用户输入并拆分它们(如果我没记错的话,进行标记)。它们非常基础,因为我是从互联网教程中学习这些功能的。

char *commandInput() {
    char *command = NULL;
    ssize_t bufsize = 0;
    getline(&command, &bufsize, stdin);
    return command;
}

char **splitLine(char *command) {
    int bufsize = 64, 
    int position = 0;
    char **tokens = malloc(bufsize * sizeof(char*));
    char *token;

    token = strtok(command, DELIMITER); 
    while (token != NULL) { 
        tokens[position] = token; 
        position++;

        if (position >= bufsize) { 
            bufsize += 64;     
            tokens = realloc(tokens, bufsize * sizeof(char*));
        }
            token = strtok(NULL, DELIMITER); 
    }
    tokens[position] = NULL; 
    return tokens;
}

如果我输入空行,任何人都可以帮助我识别导致 seg.fault 的原因吗?谢谢。

编辑

我使用了调试器(经过多次尝试终于成功使用它),结果发现错误位于我没想到会导致任何问题的行(参见---UPDATE----)。

他们处理我的 commandInput 函数的方式是在 main() 函数中,我写了

int main () {
......
    char * command = NULL
    char **args;
    command = commandInput();
    args= splitLine(command);

    ------------------ UPDATE!(CAUSING ERROR IF STATEMENT) ---------------
    background = 0
    numbarguments = 0

    // Condition to check whether there is a start program running in       backgrond
    if (!(strncmp(args[numbarguments - 1], "&",1))) {
       background = 1;
       args[numbarguments - 1] = NULL;
    }

    ----------------------------------------------

    if (args[0] == NULL || !(strncmp(args[0],"#",1))) {
        exitstat = 0;
    }
    ....... //(comparing the arguments other than null)
}

因此,有关导致我出现 seg.fault 的 if 条件的任何建议。谢谢。

【问题讨论】:

  • 你也应该检查realloc的返回值,它并不总是成功
  • 你能分享你的完整代码,它有 main() 来测试这些功能吗?
  • @cm161 是的,我刚刚编辑了帖子
  • 这个!(strncmp(args[0],"#",1)可以简化为args[0] == '#'。附带说明一下,在 shell 中,# 是注释,即使它不是该行中的第一个字符。 ls -l # echo hi 产生目录列表,但 echo hi 永远不会在有或没有 ; 分隔符的情况下执行。
  • args 在哪里获取它的值?是main()的第二个参数吗?不应该是int main(int argc, char **args)吗?

标签: c shell


【解决方案1】:

你传递给 splitline 的参数被修改了。 strtok 具有通过插入 \0 并返回指向子字符串的指针来修改它获得的字符串的效果。 strtok 返回的不是你可以直接存储以备后用的东西,而是你需要制作它的副本。

 token = strtok(command, DELIMITER); 
 while (token != NULL) 
 { 
   tokens[position] = malloc(strlen(token)+1); 
   strcpy(tokesn[position],token);
...

因此,换句话说,仅分配指向字符串的指针数组是不够的,您还需要分配空间来保存您使用 strtok 标记的字符串。


代码

if (!(strncmp(args[numbarguments - 1], "&",1))) {
   background = 1;
   args[numbarguments - 1] = NULL;
}

看起来不对,numberarguments 最初为 0,因此您将 args[-1]"&" 进行比较,然后您分配 args[-1] = NULL,这可能会导致 seg 错误。

【讨论】:

  • 这实际上很有意义。但是,它仍然会导致 seg.fault。我开始想,我需要使用free()吗?
  • 是的,你总是需要释放你的 malloc/calloc,但如果你遇到 seg 错误,它与 free 无关
  • 我编辑了我的问题。我添加了另一个信息,我如何处理来自 commandInput 函数的值
  • @Cyber​​Spock:你指的是哪个getline()? POSIX getline() 肯定会 null 终止它读取的字符串。
  • 我已经更新了我的问题,因为我终于找到了 seg 故障的根源,但我不知道如何处理它。
猜你喜欢
  • 2010-11-30
  • 2013-02-17
  • 2017-09-19
  • 2018-11-12
  • 2011-06-14
  • 2011-05-12
  • 1970-01-01
  • 1970-01-01
  • 2018-09-19
相关资源
最近更新 更多