【问题标题】:C adding array elements cause segmentation faultC添加数组元素导致分段错误
【发布时间】:2012-06-22 20:34:25
【问题描述】:

我已经阅读了几个论坛,但找不到解决这个问题的方法。

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");

我错过了什么?

【问题讨论】:

  • 我也试过这个没有malloc。
  • strcpy(serverArgs[2], "/dev/server1/trunk/build.xml"); 行可能不好 -- 该字符串大于 20 个字符。
  • @Peter 您应该将其添加为答案(而不是对问题的评论)。
  • 另一件需要注意的事情:strcpy 的使用通常是不受欢迎的,正是因为这个原因——创建缓冲区溢出太容易了。使用 strncpy 并提供明确的长度。
  • @JustinSpahr-Summers,strncpy 可能比 strcpy 更“不受欢迎”,因为您必须注意结果总是以 nul 终止。

标签: c arrays exec


【解决方案1】:

将我的评论变成答案:行 strcpy(serverArgs[2], "/dev/server1/trunk/build.xml");可能不好——那个字符串大于 20 个字符。您应该完全确定您malloc 有足够的空间容纳可能进入数组的所有内容。

【讨论】:

    【解决方案2】:

    查看execv 的手册页:

    指针数组必须以 NULL 指针终止。

    【讨论】:

    • 好的,但我认为我什至不能走那么远,因为添加第二个元素时它会崩溃。这是我的目标: char serverArgs[] = {"ant", "-f", "/dev/server1/trunk/build.xml", "solr-stop", "solr-start",(char ) 0};但我需要确定要包括哪些/多少个选项。
    • 鉴于我们看到的代码,它在该行崩溃是没有意义的,除非malloc 返回NULL。无论如何,人们应该始终检查这一点,但在这种情况下,更是如此。添加NULL 检查,为长字符串调整malloced 大小,为终止NULL 使数组更长,然后重试。如果它仍然崩溃,我们需要更多的代码,因为那应该是不可能的。
    • 好的,这就是我现在的位置: int sIndex = 3; char *serverArgs[serverCommandCount + 4]; for(index = 0; index 现在它进入 execv() 命令,但在那里崩溃。这是我编译时收到的消息:警告:从不兼容的指针类型传递'execv'的参数2
    • 没关系,最后我忘记了 null。现在可以了,谢谢!
    • 让循环只为index &lt; serverCommandCount + 3运行,因为最后一个指针应该是NULL。不要忘记在复制循环之后设置serverArgs[sIndex] = NULL(在此之前释放未使用的分配存储)。不兼容的指针类型应该是因为 execv 需要一个 char *const argv[],这不应该导致崩溃。
    【解决方案3】:

    您的第二个解决方案通常是好的解决方案,但如果您的平台上有它,请使用strdup 而不是mallocstrcpy 一次性分配和复制字符串。如果你没有strdup,自己写一个也不是什么难事。

    另外,对于你的字符串数组,你不会感到惊讶,这样做:

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

    正确初始化所有指针。

    【讨论】:

    • 我不太明白 strdup 在这种情况下是如何工作的,你能给我举个例子吗?
    • 你会使用类似serverArgs[i] = strndup("foo bar baz mumble pies", 19);的东西。这将复制“foo...”字符串最多 19 个字符(缓冲区的大小减去末尾的一个空字符),并将其放入数组中。试试man strdup
    • “缓冲区的大小减去一个空字符”——这里没有缓冲区(可以/应该省略 malloc 循环)。 strdup,而不是 strndup,是在这里使用的正确函数。 strndup 的用例很少,但这不是其中之一。
    猜你喜欢
    • 2014-08-12
    • 2010-12-18
    • 2017-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-19
    • 1970-01-01
    相关资源
    最近更新 更多