我正在执行的代码中,我首先通过管道然后通过空格分割命令。分割错误 - 将命令分割为令牌
int main(){
pid_t pid;
while (1) {
printf("$ ");
char *cmd;
ssize_t size=0;
getline(&cmd,&size,stdin);
if (cmd[strlen(cmd)-1]== '\n') {cmd[strlen(cmd)-1]='\0';}
char** commands = splitter(cmd,"|");
int i=0;
int fd[2],in=0;
while (commands[i+1]!=NULL){
pipe(fd);
char **args = splitter(commands[i]," \t");
pid = fork();
if (pid==-1) {exit(EXIT_FAILURE);}
else if (pid==0){
close(fd[0]);
changeIO(in,0);
changeIO(fd[1],1);
execvp(args[0],args);
}
else{
waitpid(pid,NULL,0);
close(fd[1]);
close(in);
in = fd[0];
}
i++;
}
char **args = splitter(commands[i+1]," \t");
changeIO(in,0);
execvp(args[0],args);
}
}
这里如下的功能的实现上面的代码使用
void changeIO(int oldfd,int newfd){
if (oldfd!=newfd){
dup2(oldfd,newfd);
close(oldfd);
}
}
char** splitter(char* stringToSplit, char* delimiter){
char *token;
int initial_size = 300;
char** args = malloc(initial_size*sizeof(char*));
token = strtok(stringToSplit,delimiter);
int index = 0;
while (token != NULL) {
args[index] = token;
index++;
if (index >= initial_size) {
initial_size = initial_size + 100;
args = realloc(args,initial_size*sizeof(char*));
if (!args) exit(EXIT_FAILURE);
}
token = strtok(NULL,delimiter);
}
args[index] = NULL;
return args;
}
确定执行代码我得到分割故障,当我在所述用户输入输入该命令。测试各种选项后,我意识到它与char** args
有关,其中我传递了每个命令的标记。我不明白为什么会发生这种情况,因为分配内存,并从我的理解,我只是指针指向分配的内存。任何帮助赞赏。
编辑:用valgrind检查。结果如下:
==3361== Memcheck, a memory error detector
==3361== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==3361== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==3361== Command: ./mysh3
==3361==
==3361== Conditional jump or move depends on uninitialised value(s)
==3361== at 0x40AFE97: getdelim (iogetdelim.c:59)
==3361== by 0x40ACDD1: getline (getline.c:32)
==3361== by 0x80486C4: main (in /home/dimitris/Desktop/mysh3)
==3361==
$ ls
==3361== Invalid read of size 1
==3361== at 0x4101CAA: execvpe (execvpe.c:50)
==3361== by 0x4101B33: execvp (execvp.c:26)
==3361== by 0x804885F: main (in /home/dimitris/Desktop/mysh3)
==3361== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==3361==
==3361==
==3361== Process terminating with default action of signal 11 (SIGSEGV)
==3361== Access not within mapped region at address 0x0
==3361== at 0x4101CAA: execvpe (execvpe.c:50)
==3361== by 0x4101B33: execvp (execvp.c:26)
==3361== by 0x804885F: main (in /home/dimitris/Desktop/mysh3)
==3361== If you believe this happened as a result of a stack
==3361== overflow in your program's main thread (unlikely but
==3361== possible), you can try to increase the size of the
==3361== main thread stack using the --main-stacksize= flag.
==3361== The main thread stack size used in this run was 8388608.
==3361==
==3361== HEAP SUMMARY:
==3361== in use at exit: 2,520 bytes in 3 blocks
==3361== total heap usage: 5 allocs, 2 frees, 4,568 bytes allocated
==3361==
==3361== LEAK SUMMARY:
==3361== definitely lost: 0 bytes in 0 blocks
==3361== indirectly lost: 0 bytes in 0 blocks
==3361== possibly lost: 0 bytes in 0 blocks
==3361== still reachable: 2,520 bytes in 3 blocks
==3361== suppressed: 0 bytes in 0 blocks
==3361== Rerun with --leak-check=full to see details of leaked memory
==3361==
==3361== For counts of detected and suppressed errors, rerun with: -v
==3361== Use --track-origins=yes to see where uninitialised values come from
==3361== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Segmentation fault
你使用过调试器吗?如果您希望我们提供帮助,请提供[mcve]。我们无法调试不完整的代码。例如,什么是'cmd'? – kaylum
可能是未初始化的fd [2]数组。这也可能是一个CMD变量本身的问题,我不知道它是如何初始化的。对于像这样的错误,我喜欢http://valgrind.org/,以防你在Linux上。不过,我同意@kaylum调试器信息真的有助于理解你的问题:) – PlatinTato
@JacobusConradi我将用valgrind测试它并更新我的文章。谢谢。 –