c - 如何将 char* 传递给函数?

标签 c pointers

我试过这段代码!我不明白它是如何工作的。

     int main()
     {
         char *s1;
         s1=malloc(sizeof(char)*20);
         strcpy(s1,"main");
         printf("%s\n",s1);
         func(s1);
         printf("After call %s\n",s1);
         return 0;
      }
      void func(char *s2)
      {
         //free(s2);<--------------(this is what I'm talking about)
         s2=malloc(sizeof(char)*25);
         strcpy(s2,"func");
         printf("fun---%s\n",s2);
      }

输出:

     main
     fun---func
     After call main

但是如果在 func() 中添加注释行输出是

输出:

     main
     fun---func 
     After call main

我想知道整个事情是如何运作的。我的意思是 s1char*。分配后它指向一 block 内存。在 C 中,一切都是按值传递的。因此,当我们传递它时,将在 (stack) main 的局部范围内创建另一个变量,该变量保存分块内存的地址(即,s1 包含相同的值) .

  • 现在,如果我们分配,那么就没有机会在 main() 中反射(reflect) s1 中的变化。因为 s1 永远不会改变。
  • 但如果我们释放它,那么在调用函数 func() 后,我应该在 printf() 的 main 中得到一个垃圾值。

这是正确的想法吗?如果不是请清除概念。在 Windows 中,它给出了我告诉你的结果。但在 Linux 中,它以某种方式反射(reflect)了这种变化。

我错过了什么?

最佳答案

你(大部分)是对的。

在函数中释放 s2(并因此释放 s1),然后在返回 main() 时使用 s1就是所谓的未定义行为。

您不应该这样做,因为标准要求几乎任何 都允许发生,问题是,“任何事情”都包含它起作用的可能性。

为什么它能正常工作几乎可以肯定是因为没有其他人再次分配该内存块并覆盖其中的数据,所以它仍然包含原来在那里的内容。

如果在调用 func() 和打印 s1 之间的 main() 中,您插入了:

char *s3 = malloc(10000);
strcpy (s3, "Yoohoo, I'v changed");

那么您可能会发现打印 s1 会给您不同的结果。

或者,因为它是 UB,也许不是 :-)

建议避免未定义的行为,即使它看起来有效。更改您的编译器、编译器标志或代码的顺序,甚至在蓝色月亮上编译,可能会以意想不到的方式改变您的代码的工作方式。


如果你想传回函数中分配的指针(除了使用return),你可以使用双重间接:

void allocStr (char **pStr) {
    free (*pStr);
    *pStr = malloc (1000);
}
:
char *xyzzy = NULL;
allocStr (&xyzzy);

这就是您在 C 中执行按引用传递的方式。

关于c - 如何将 char* 传递给函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25666301/

相关文章:

函数C中的char**和valgrind条件跳转报错

c++ - 从 C++ 函数返回指针的推荐方法?

c++ - 未处理的异常,传递对象?

c++ - 这是通过引用传递文件指针的正确语法吗?

c - 如何使我的程序 "forget"成为我在键盘上按下的字母?

c - 如何获取打开文件的结构文件?

c++ - 将 C 代码转换为 .net(C# 或 VB.net)

c - MPI_Scatterv 段错误

c - 在 Gtk+2.0 应用程序中使用 pthreads 的安全性

c++ - 为什么我们在这里将 0 添加到双空指针?