【发布时间】:2014-10-13 19:31:00
【问题描述】:
我的程序已经完全完成,并且完全可以在 Ubuntu 12.04 中正常运行。但是,当我尝试在 Debian VM 上编译它时,它给了我一个段错误。给出段错误的代码是:
printf("Going to location: /bin/%s\n", input2[0]);
Input2 是一个 char*,因为我需要使用 strtok 函数(我相信需要 char* 作为参数)。我在下面发布了我的代码,以及 Eclipse 调试的变量窗口以显示数组中的值。
这是帮助解决我的问题的变量窗口:
我最初认为错误出在 array2 本身,因为未使用的值以 0x0 而不是 \0 结尾。后来我发现 0x0 和 \0 只是表达空终止符的不同方式,所以这不是问题。我也试过了
printf("Going to location: /bin/%s\n", *input2[0]);
使用取消引用,因为 input2 应该是指向字符串的指针,但这也不起作用。
我在这里很困惑;问题是由于 Ubuntu 和 Debian 之间的差异造成的,还是实际上是因为我使用阵列的方式造成的?我倾向于后者,但我很困惑哪里出了问题。
这是我的代码,直到出现段错误。剩下的就是 fork() 和 execvp(),效果很好:
int flag = 0;
int i = 0;
int status;
char *s; //for strchr, strtok
char input[15] = "";
char *input2[5];
//char input2[5];
//Prompt
printf("Please enter prompt:\n");
//Reads in input
fgets(input, 14, stdin);
//Remove \n
int len = strlen(input); //Warning: Implicit declaration of strlen and Incompatible implicit declaration of built-in function strlen
if (len > 0 && input[len-1] == '\n')
input[len-1] = ' ';
//Check for & via strchr
s = strchr (input, '&'); //Warning: Implicit declaration of strchr and Incompatible implicit declaration of built-in function strchr
if (s != NULL) { //If there is a &
printf("'&' detected. Program not waiting.\n");
//printf ("'&' Found at %s\n", s);
flag = 1;
}
//Now for strtok
input2[i] = strtok(input, " "); //Warning: Implicit declaration of function strtok and Assignment makes pointer from integer without cast
while(input2[i] != NULL)
{
input2[++i] = strtok( NULL, " "); //Assignment makes pointer from integer without cast
}
if (flag == 1) {
i = i - 1; //Removes & from total number of arguments
}
//Sets null terminator for unused slots. (Is this step necessary? Does the C compiler know when to stop?)
int c = i;
while (c < 5) {
input2[c] = '\0';
c++;
}
printf("Going to location: /bin/%s\n", input2[0]); //SegFault
编辑:我已将警告作为 cmets 添加到我的代码中。它们中的大多数是隐式声明警告,还有一些是“Assignment make pointer from integer without cast”。我现在会检查这些。
【问题讨论】:
-
这个问题肯定与你的程序有关。这从根本上不是由于 Ubuntu 和 Debian 之间的差异。如果你的程序有段错误,那么这是一个非常安全的假设,它是你的错误。
-
fgets(input, 100, stdin)放入仅声明为char input[15]的缓冲区中,从一开始就写满了灾难的秘诀。 -
15 和 100 的差异是我的错!实际代码为 15;我之前正在改变一些事情。 “ls”和“pwd”将是唯一的输入。我一直在尝试其他各种方法,但仍未找到解决方案。
-
你试过通过 valgrind 运行吗?能够使用 valgrind 是一项非常有价值的技能,将来可能会派上用场。
-
关于您的文本:“我后来发现 0x0 和 \0 只是表达空终止符的不同方式,所以这不是问题。”。它们根本不一样。 0 是一个空指针。指向任何非法解除引用的指针。而指向值 0 (
'\0') 的非零指针是一个空字符串。您忽略的那些警告是您的程序中需要修复的错误。
标签: c linux segmentation-fault debian strtok