C代码在Windows中崩溃,但在Linux中不崩溃

我是C的新手,我一直在Fedora中testing我的程序,使用gcc和gdb进行debugging。 我有一个程序,从用户的input。 如果input的第一个string是“创build”,那么我看看第二个命令,如果这是“对象”,那么我继续到createObject函数。

希望我的代码能使这个更清晰一点:

static void parseCmd(char **input) { if(!strcmp(input[0], "create")) { if(!strcmp(input[1], "object")) { if(input[2] && strcmp(input[2], "")) createObject(input[2]); else printf("Object needs a name\n"); } else printf("Command needs more parameters\n"); } else printf("Command not recognized\n"); } 

当我testing进入只是“创build对象”(没有空间后的对象,只是ENTER键)

在Linux中打印“对象需要名称”

但在Windows中,程序崩溃,它只是挂起。 我怎么能改变代码,使其在Linux中的行为相同?

Solutions Collecting From Web of "C代码在Windows中崩溃,但在Linux中不崩溃"

你已经进入了潜在的访问违规或未定义的行为(以及未定义的值):

 input[2] && strcmp(input[2], "") 

如果input的长度只有2,那么这是阅读超过可接受的点阅读。 最糟糕的情况是这会导致段错误(就像Windows一样),最好的情况是操作系统会让它发生,你会得到一个随机值。 (虽然Linux似乎将它或* input [2]视为0)。

无论如何,不​​要阅读你不允许访问的内容,而是传递输入的长度,然后检查。

 static void parseCmd( char **input, size_t num) { //or just int if size_t isn't already defined //compare num } 

– 编辑 –

正如Daniel Fischer所指出的那样,显然argv[argc]确实是一个有效的读,并且保证是一个空指针。

假设你确实将argv传递给函数,这意味着你可以依赖这个行为。 你的另外两个if语句不检查这个,为了泛化这个函数,最好还是传递一下长度(或者像paulsm4说的那样,你应该看一下getopt函数 – 它使得参数比滚动你自己的解析方法更容易)。

你有代码说:

 if(input[2] && strcmp(input[2], "")) 

显然试图检测input[2]是否存在,而不是空的。

但是,这是行不通的。 没有承诺,缺少第三个参数将使input[2]为NULL或""

input[2]在这一点上可能会有一个垃圾值,但垃圾仍然会通过你的测试!

你有几个选项来解决它。
要么这个函数的调用者需要保证未被设置为有效数据的元素将被设置为零/零。

或者,我更喜欢的方法是将函数签名更改为如下所示:

 static void parseCmd(char **input, int num_inputs); 

并将输入数与输入数组一起传递。

你在这一行有一个问题:

 if(input[2] && strcmp(input[2], "")) 

在你的测试中输入[2]不存在“创建对象”,这就解释了为什么它会崩溃。

希望这个帮助。

问候。

你先生正在打你没有打的记忆。

我介绍你

如何检查指针是否有效?

任何人想知道他是如何传递的:

 int main(void) { char* values[] = {"1", "2", "3"}; parseCmd(values); } 

当你尝试访问输入[2]的时候,它正在发生,但是如果你不知道你正在接受什么,它可能会发生。当你得到输入时,我会建议进行完整性检查。 如果他们不把任何东西放在值[2]让你的功能意识到这一点,或改变它处理它的方式。 使用指针和指针指针时,您不能吝啬健全性检查分配值时。