Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
execvp的地址错误_C_Shell_Unix_Operating System_Execvp - Fatal编程技术网

execvp的地址错误

execvp的地址错误,c,shell,unix,operating-system,execvp,C,Shell,Unix,Operating System,Execvp,我正在尝试制作一个shell“bosh>”,它接受Unix命令并不断得到错误的地址。我知道我的代码读取命令并解析它们,但由于某种原因,我无法让它们执行,相反,我得到了一个“坏地址”错误 #包括 #包括 #包括 #包括 #包括 #包括 #包括 #定义MAX_第128行 #定义最大参数10 int main(){ pid_t pid; char命令[MAX_LINE];/*命令行缓冲区*/ char*commandArgs[MAX_ARGS];/*命令行arg*/ int i; char*sPtr=

我正在尝试制作一个shell“bosh>”,它接受Unix命令并不断得到错误的地址。我知道我的代码读取命令并解析它们,但由于某种原因,我无法让它们执行,相反,我得到了一个“坏地址”错误

#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义MAX_第128行
#定义最大参数10
int main(){
pid_t pid;
char命令[MAX_LINE];/*命令行缓冲区*/
char*commandArgs[MAX_ARGS];/*命令行arg*/
int i;
char*sPtr=strtok(命令“”);
int n=0;
printf(“波什>”);
fgets(命令,最大行-1,标准输入);
命令[strlen(命令)-1]='\0';
while(strcmp(命令,“退出”)!=0)
{
n=0;
sPtr=strtok(命令“”);

而(sPtr&&n这两条线是罪魁祸首:

commandArgs[0]=malloc(strlen(command)+1);
strcpy(commandArgs[0],command);
首先,
malloc(strlen(…)
后跟
strcpy
是POSIX函数已经做过的事情。但是,您甚至不需要复制字符串-只需将指向原始字符串的指针存储到
commandArgs[0]

commandArgs[0] = command;
但是,这个命令将接受多少参数呢?如果你仔细阅读手册,他们会说:

execv()
execvp()
,和
execvpe()
函数提供指向以null结尾的字符串的指针数组,这些字符串表示新程序可用的参数列表。按照惯例,第一个参数应指向与正在执行的文件关联的文件名。指针数组必须以null指针结尾。

您的参数数组不是以NULL结尾的。若要修复它,请使用

commandArgs[0] = command;
commandArgs[1] = NULL; // !!!!


(然后您会注意到,您实际上希望在
strtok
解析循环中分配参数,这样您就可以将所有参数分配到
commandArgs
数组中;并在启用所有警告的情况下编译并处理这些警告,依此类推)。

这两行是罪魁祸首:

commandArgs[0]=malloc(strlen(command)+1);
strcpy(commandArgs[0],command);
首先,
malloc(strlen(…)
后跟
strcpy
是POSIX函数已经做过的事情。但是,您甚至不需要复制字符串-只需将指向原始字符串的指针存储到
commandArgs[0]

commandArgs[0] = command;
但是,这个命令将接受多少参数呢?如果你仔细阅读手册,他们会说:

execv()
execvp()
,和
execvpe()
函数提供指向以null结尾的字符串的指针数组,这些字符串表示新程序可用的参数列表。按照惯例,第一个参数应指向与正在执行的文件关联的文件名。指针数组必须以null指针结尾。

您的参数数组不是以NULL结尾的。若要修复它,请使用

commandArgs[0] = command;
commandArgs[1] = NULL; // !!!!


(然后您会注意到,您实际上希望在
strtok
解析循环中分配参数,这样您就可以将所有参数实际分配到
commandArgs
数组中;并在启用所有警告的情况下编译并解决这些警告,依此类推).

您可以在声明中初始化
sPtr
,您不需要这样做,因为您从不使用初始值。但是初始化会产生未定义的行为,因为它取决于
命令
数组的内容,而该数组在该点上是不确定的

作为第二个参数传递给
execvp()
的数组应在最后一个参数后包含空指针。您不能确保您的数组包含空指针


此外,由于未能将令牌分配给
commandArgs[]
,您似乎删除了输入命令的所有参数。标记化后,您将复制第一个令牌(仅)并将副本分配给
commandArgs
的第一个元素,但忽略任何其他标记。

在声明中初始化
sPtr
,这是不需要的,因为您从不使用初始值。但是初始化会产生未定义的行为,因为它取决于
命令的内容在那一点上是不确定的

作为第二个参数传递给
execvp()
的数组应在最后一个参数后包含空指针。您不能确保您的数组包含空指针


此外,由于未能将标记分配给
commandArgs[]
,您似乎删除了输入命令的所有参数。标记化后,您确实复制了第一个标记(仅)并将副本分配给
commandArgs
的第一个元素,但忽略了任何其他标记。

首先,图片中的狗很好。终止的空字节('\0')存储在缓冲区中由
fgets
读取的最后一个字符之后。因此,您不必放置一个
'\0'
@TonyTannous来剥离换行符…(尽管它也不正确)。在切掉它之前,您需要检查最后一个字符是否确实是
'\n'
。我不确定,但我认为在命令参数中放置参数的方式存在问题。您只存储第一个参数。最后一个参数必须为NULL。首先,图片中的狗很好。一个终止的NULL字节('\0')存储在缓冲区中由
fgets
读取的最后一个字符之后。因此,您不必放置一个
'\0'
@TonyTannous来剥离换行符…(尽管它也不正确)。在切掉它之前,您需要检查最后一个字符是否确实是
'\n'
。我不确定,但我认为在commandArgs中放置参数的方式存在问题。您只存储第一个参数。最后一个参数必须为NULL。我在注释中指出了这一点。argumen有问题t初始化。可能只分配了第一个参数,最后一个参数后没有空值。+1我已经指出