使用命令行参数对execvp进行Segfault

时间:2017-09-07 20:41:02

标签: c segmentation-fault execvp

我正在编写一个编程任务,要求我编写一个能够从命令行读取命令的代码及其参数,并使用execvp执行程序。 这是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main(int argc, const char * argv[]) {

    char **cmd;
    int i;

    if (argc == 1){

        fprintf(stdout, "No command inserted!\n");
        exit(EXIT_SUCCESS);

    }

    cmd = (char **) malloc( argc * sizeof(char *));
    cmd[0] = strdup(argv[1]);

    if (argc > 2){

    for (i = 1 ; i < argc - 1  ; i++ ){

            cmd[i] = (char *) malloc( strlen(argv[i+1]) * sizeof(char) );
        strcpy(cmd[i], argv[i+1]);

    }

    cmd[argc] = NULL;
    execvp(cmd[0], cmd);

    fprintf(stderr, "Failed Execution or not existing command!!\n");
    exit(EXIT_FAILURE);

    }

    cmd[1] = NULL;

    execvp(cmd[0], cmd);

    fprintf(stderr, "Failed Execution or not existing command!!\n");
    exit(EXIT_FAILURE);

    return 0;
}

代码可以正常输入无参数命令,例如:

./a.out who
./a.out ls

但会导致“细分错误:11&#39;在编写如下命令时:

./a.out ls -l
./a.out more file.txt

我无法弄清问题在哪里......

2 个答案:

答案 0 :(得分:0)

至少有两个点超出数组范围:

cmd[i] = (char *) malloc( strlen(argv[i+1]) * sizeof(char) )

是一次性的,因为它不考虑终止\0 - 字符,因此strcpy(cmd[i], argv[i+1])将超过边界。写......

cmd[i] = (char *) malloc( (strlen(argv[i+1]) + 1) * sizeof(char) )

代替。顺便说一句:根据定义,sizeof(char)始终为1

此外,

cmd = (char **) malloc( argc * sizeof(char *));
...
cmd[argc] = NULL;

再一次关闭。如果您想分配cmd = (char **) malloc( (argc+1) * sizeof(char *)),则应为cmd[argc] = NULL

答案 1 :(得分:0)

我有类似的问题。 execvp()似乎什么都不做,但实际上我运行它的子进程崩溃了一个段错误。该修复程序最终修复了用于存储输入的不同转换的字符数组。我根本没有使用malloc()用于其中一些阵列(我不是C人,并且不为这个错误感到骄傲),这只是随着程序变得越来越复杂而成为一个问题。对于带到这里的普通用户,我建议仔细检查未分配的指针,或者如上所述,检查大小不足的指针。即使传递给execvp()的数组已正确分配并且具有正确类型所需的内容(通过GDB确定),这也发生在我身上。