使用命令行参数在 execvp 上出现段错误

Segfault on execvp using command line arguments

我正在做一项编程作业,要求我编写一段代码,能够从命令行读取命令及其参数,并使用 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

但在编写如下命令时会导致 'Segmentation Fault:11':

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

我想不通问题出在哪里...

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

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

是一个关闭,因为它不考虑终止 [=13=] 字符,这样 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.

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