【问题标题】:c string pointerc 字符串指针
【发布时间】:2013-03-11 11:58:14
【问题描述】:

我开始学习 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; }

提前谢谢各位。

【问题讨论】:

  • 你打算用send_args()做什么?我不确定您的数组是否已正确初始化并且可以保存所有值。我认为编译器可能会优化最后两个 NULL 并且您可能会写入未引用的内存。
  • 不,编译器无法优化数组元素正是因为这个原因:数组的大小是程序数据的相关部分。

标签: c string pointers


【解决方案1】:

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

【讨论】:

  • 我认为 OP 调用 free 是因为他调用了 strdup,它确实调用了 malloc
  • strdup 执行隐式 malloc。
  • free 因为我做了strdup,这是为char指针分配内存。谢谢
【解决方案2】:

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

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

const char *str[3];
str[0] = "nice!";
str[1] = "abc";
str[2] = "def"
send_args(3, str); 

【讨论】:

    【解决方案3】:

    是的,它们完全有效。不过,您需要关注argc,因为您将其增加了一倍。只要您正确处理它,它不会导致任何“不良影响”。您可以查看您的代码示例here

    【讨论】:

      【解决方案4】:

      如果您询问自动存储持续时间,您的 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 被销毁,因为执行已经超过了它在其中创建的块的末尾,并且返回的指针将指向垃圾。

      【讨论】:

        【解决方案5】:

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

        但是如果你对"nice!"使用一个本地字符数组,它就无效了,因为send_args不能读取其他函数的本地变量。

        【讨论】:

          猜你喜欢
          • 2012-03-22
          • 1970-01-01
          • 2011-04-12
          • 1970-01-01
          • 2021-06-28
          • 2023-03-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多