4

我开始学习 C,我对 c 字符串指针有点困惑。

int argc = 0;
const char *str[] = { "hello" , NULL, NULL };
str[argc++] = "nice!";
str[argc++] = "abc";
str[argc++] = "def"
send_args(argc, str); 
//the prototype/header : int send_args(int argc, const char **args);

因为 send_args 函数不会修改传递的 str 的值,这些操作是否有效?因为我不想做类似的事情:

int i, argc = 0;
char *str[3];
str[argc++] = strdup("nice!");
str[argc++] = strdup("abc");
str[argc++] = strduo("def)"
send_args(argc, str);
for (i = 0; i< argc; i++)
    if (str[i]) { free(str[i]); str[i]=NULL; }

提前谢谢各位。

4

5 回答 5

4

我认为第一个示例没有任何问题。

于 2013-03-11T12:02:03.617 回答
1

是的,没关系。字符串文字可能放置在初始化的数据部分(细节由实现定义),并且不需要(事实上,甚至不可能)释放文字。的类型str与 所需的类型兼容send_args,所以一切都很好。

请注意,正如所写,str[]用三个元素初始化,因此不能保存四个或更多指针。你可以通过声明和初始化来达到同样的效果

const char *str[3];
str[0] = "nice!";
str[1] = "abc";
str[2] = "def"
send_args(3, str); 
于 2013-03-11T12:04:59.283 回答
0

是的,它们是完全有效的。不过,您需要担心,argc因为您将其增加了一个。只要您正确处理它,它就不会造成任何“不良影响”。您可以在此处查看您的代码示例

于 2013-03-11T12:41:20.823 回答
0

如果您要询问自动存储持续时间,str那么在执行到达创建它的块的末尾之前,您的数组不会被销毁。

const char **fubar(void)
{
    int argc = 0;
    const char *str[] = { "hello" , NULL, NULL }; /* str is created here */
    str[argc++] = "nice!";
    str[argc++] = "abc";
    str[argc++] = "def"
    send_args(argc, str); /* the lifetime of str is still valid here */
    return str; /* ... but str gets destroyed after this "return" statement */
}

int main(void) {
  const char **fubared = fubar();
  /* str has already been destroyed, and fubar's return value has been rendered garbage */
  /* so using fubared would be a bad idea. */
  return 0;
}

return导致 str 被销毁,因为执行已经超过了在其中创建它的块的末尾,并且返回的指针将指向垃圾。

于 2013-03-11T12:46:00.003 回答
-1

在这种情况下它们是有效的,因为字符串在编译时是静态存储的,不能被释放。它们的指针地址也不取决于您所在的功能。

但是,如果您将本地字符数组用于"nice!",它将无效,因为 send_args 无法读取其他函数的局部变量。

于 2013-03-11T12:06:29.100 回答