2012-06-22 55 views
0

我已经阅读了几个论坛,但找不到解决方案。C添加数组元素导致分段错误

int sIndex = 3; 
char serverArgs[serverCommandCount + 3][20]; 


strcpy(serverArgs[0], "ant"); 
strcpy(serverArgs[1], "-f"); 
strcpy(serverArgs[2], "/dev/server1/trunk/build.xml"); 
if(serverStop){strcpy(serverArgs[sIndex], "jboss-stop"); sIndex++;} 
if(serverClean){strcpy(serverArgs[sIndex], "clean"); sIndex++;} 
if(serverDeploy){strcpy(serverArgs[sIndex], "deploy"); sIndex++;} 
if(releaseDB){strcpy(serverArgs[sIndex], "releasedb"); sIndex++;} 
if(createDB){strcpy(serverArgs[sIndex], "createdb"); sIndex++;} 
if(serverStart){strcpy(serverArgs[sIndex], "jboss-start"); sIndex++;} 
if(serverDebug){strcpy(serverArgs[sIndex], "jboss-start-debug"); sIndex++;} 

execv(antEx, serverArgs); 

在这个解决方案中,问题是execv需要char * []而不是char []。

int sIndex = 3; 
char *serverArgs[serverCommandCount + 3]; 

for(index = 0; index < serverCommandCount + 3; index++) 
    serverArgs[index] = malloc(20); 
strcpy(serverArgs[0], "ant"); 
strcpy(serverArgs[1], "-f"); 
strcpy(serverArgs[2], "/dev/server1/trunk/build.xml"); 
if(serverStop){strcpy(serverArgs[sIndex], "jboss-stop"); sIndex++;} 
if(serverClean){strcpy(serverArgs[sIndex], "clean"); sIndex++;} 
if(serverDeploy){strcpy(serverArgs[sIndex], "deploy"); sIndex++;} 
if(releaseDB){strcpy(serverArgs[sIndex], "releasedb"); sIndex++;} 
if(createDB){strcpy(serverArgs[sIndex], "createdb"); sIndex++;} 
if(serverStart){strcpy(serverArgs[sIndex], "jboss-start"); sIndex++;} 
if(serverDebug){strcpy(serverArgs[sIndex], "jboss-start-debug"); sIndex++;} 

execv(antEx, serverArgs); 

当我尝试这种方式,我得到一个分段错误,当它试图执行

strcpy(serverArgs[1], "-f");

我缺少什么?

+0

我也试过这个没有malloc。 –

+4

行strcpy(serverArgs [2],“/dev/server1/trunk/build.xml”);'可能不太好 - 该字符串大于20个字符。 – Peter

+0

@Peter你应该添加一个答案(而不是对问题的评论)。 –

回答

1

检查execv手册页:

指针数组必须由一个NULL指针终止。

+0

好吧,但我不认为我甚至可以得到那么远,因为它添加第二个元素时崩溃。这是我的目标: char * serverArgs [] = {“ant”,“-f”,“/dev/server1/trunk/build.xml”,“solr-stop”,“solr-start”,(char *)0}; 但我需要确定包含哪些/多少选项。 –

+0

鉴于我们看到的代码,它没有任何意义,它崩溃在那一行,除非'malloc'返回NULL。无论如何,总是要检查,但在这种情况下,更是如此。添加'NULL'检查,为长字符串调整'malloc'的大小,让你的数组延长'NULL'并重试。如果它仍然崩溃,我们需要更多的代码,因为那应该是不可能的。 –

+0

好的,这里是我现在的位置: int sIndex = 3; \t \t char *serverArgs[serverCommandCount + 4]; for(index = 0; index < serverCommandCount + 4; index++) serverArgs[index] = malloc(100); ... execv(antEx, serverArgs); 现在它使它成为execv()命令但在那里崩溃。这里是我编译时得到的消息: 警告:从不兼容的指针类型传递'execv'的参数2 –

0

你的第二个解决方案通常是好的,但如果你拥有了它你的平台上,使用strdup代替mallocstrcpy在一气呵成分配和复制的字符串。如果你没有strdup,自己写一个不会很困难。

而且,你不必为你的字符串数组一个惊喜,这样做:

char *serverArgs[serverCommandCount + 3] = { 0 }; 

正确初始化所有的指针。

+0

我真的不明白strdup在这种情况下会如何工作,您能举个例子吗? –

+0

你可以使用类似'serverArgs [i] = strndup(“foo bar baz mumble pies”,19);'。这会将“foo ...”字符串最多复制19个字符(缓冲区的大小减去结尾处的一个空字符),并将其放入数组中。尝试“男子气概”。 – Peter

+0

“缓冲区的大小减去一个空字符” - 这里没有缓冲区(malloc循环可以/应该省略)。 strdup,而不是strndup,是在这里使用的正确函数。 strndup有很少的用例,但这不是其中之一。 –

2

将我的评论转换为答案:strcpy(serverArgs [2],“/dev/server1/trunk/build.xml”);可能并不好 - 字符串大于20个字符。你应该完全确定你有足够的空间来存放可能进入阵列的所有东西。