使用';execlp&x27;递归运行当前程序的系统调用

使用';execlp&x27;递归运行当前程序的系统调用,c,segmentation-fault,exec,command-line-arguments,system-calls,C,Segmentation Fault,Exec,Command Line Arguments,System Calls,我试图使用execlp在我的程序内部调用我的程序(对于一个项目),但遇到了问题。我创建了一个示例项目,它应该从n倒计时到0(基本上运行n次)。每次运行时,我都会得到第一个减量,然后出现seg故障。请让我知道我做错了什么 p.S对于C语言中的系统调用是相当新的,所以如果可能的话,请详细解释。提前谢谢 #include <stdio.h> #include <sys/types.h> #include <unistd.h> #include <stdlib.

我试图使用execlp在我的程序内部调用我的程序(对于一个项目),但遇到了问题。我创建了一个示例项目,它应该从
n
倒计时到0(基本上运行n次)。每次运行时,我都会得到第一个减量,然后出现seg故障。请让我知道我做错了什么

p.S对于C语言中的系统调用是相当新的,所以如果可能的话,请详细解释。提前谢谢

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <errno.h>
#include <time.h>

int main(int argc, char **argv)
{

    int n = atoi(argv[1]);

    char newParameters[2];
    sprintf(newParameters, "%d", n - 1);

    if (n != 0)
    {
        execlp("./tmp", newParameters, (char *)NULL);
    }

    printf("The program has finished.\n");

    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
int main(int argc,字符**argv)
{
int n=atoi(argv[1]);
新参数[2];
sprintf(新参数,“%d”,n-1);
如果(n!=0)
{
execlp(“./tmp”,newParameters,(char*)NULL);
}
printf(“程序已完成。\n”);
返回0;
}
C程序称为tmp。

来自:

这些函数的初始参数是要执行的文件名

execl()、execlp()和execle()函数中的常量char*arg和后续省略号可以看作是arg0、arg1、…、argn。它们一起描述了指向以null结尾的字符串的一个或多个指针的列表,这些字符串表示执行程序可用的参数列表。按照惯例,第一个参数应该指向与正在执行的文件关联的文件名

也就是说,
execlp
的第一个参数是要运行的可执行文件。第二个参数对应于传递给
main
argv[0]
。第三个参数是
argv[1]
等等。因此,在这种情况下,
execlp
需要:

execlp("./tmp", "./tmp", newParameters, NULL);
或者最好还是使用
argv[0]
而不是硬编码的可执行文件名,这样无论程序如何链接,它都可以工作:

execlp(argv[0], argv[0], newParameters, NULL);
其他需要注意的事项:

  • newParameters
    只能保存单个字符串(包括NUL终止符)。因此,任何数字大于9的命令行都将导致未定义的行为
  • 其他良好实践:在使用
    argv
    值之前,始终检查
    argc
    ,并始终检查所有函数调用的返回值,在这种情况下,尤其是
    execlp
来自:

这些函数的初始参数是要执行的文件名

execl()、execlp()和execle()函数中的常量char*arg和后续省略号可以看作是arg0、arg1、…、argn。它们一起描述了指向以null结尾的字符串的一个或多个指针的列表,这些字符串表示执行程序可用的参数列表。按照惯例,第一个参数应该指向与正在执行的文件关联的文件名

也就是说,
execlp
的第一个参数是要运行的可执行文件。第二个参数对应于传递给
main
argv[0]
。第三个参数是
argv[1]
等等。因此,在这种情况下,
execlp
需要:

execlp("./tmp", "./tmp", newParameters, NULL);
或者最好还是使用
argv[0]
而不是硬编码的可执行文件名,这样无论程序如何链接,它都可以工作:

execlp(argv[0], argv[0], newParameters, NULL);
其他需要注意的事项:

  • newParameters
    只能保存单个字符串(包括NUL终止符)。因此,任何数字大于9的命令行都将导致未定义的行为
  • 其他良好实践:在使用
    argv
    值之前,始终检查
    argc
    ,并始终检查所有函数调用的返回值,在这种情况下,尤其是
    execlp

execlp(2)
不能用于递归运行程序,因为没有创建新进程。使用新映射加载(覆盖)当前上下文(进程地址空间、数据等)以再次执行同一程序,并分离和丢弃数据段、堆栈段和内存段以创建新程序。当此实例最终退出(2)s时,没有备份的进程可返回。要创建新进程,您需要使用
fork(2)
,而不是
execlp(2)
execlp(2)
不能用于递归运行程序,因为没有创建新进程。使用新映射加载(覆盖)当前上下文(进程地址空间、数据等)以再次执行同一程序,并分离和丢弃数据段、堆栈段和内存段以创建新程序。当此实例最终退出(2)s时,没有备份的进程可返回。要创建新进程,您需要使用
fork(2)
,而不是
execlp(2)

什么是测试命令行
newParameters
只能保存一个字符串。因此,任何大于9的输入数字都将导致未定义的行为。应为
execlp(“./tmp”,“/tmp”,newParameters,(char*)NULL)什么是测试命令行
newParameters
只能保存一个字符串。因此,任何大于9的输入数字都将导致未定义的行为。应为
execlp(“./tmp”,“/tmp”,newParameters,(char*)NULL)这很有效。非常感谢你的帮助!这很有效。非常感谢你的帮助!