【问题标题】:Returning pointer to static (outside function) array [duplicate]返回指向静态(外部函数)数组的指针[重复]
【发布时间】:2019-01-24 17:36:54
【问题描述】:

以下代码“正确”吗?还是会是未定义的行为?

// myfile.c
static char x[10][10];

char* my_function() {
    return x[0];
}

my_function 正在共享库中使用,因此我认为在文件/编译单元之外访问其返回值是不安全的(由于 static 关键字)。

【问题讨论】:

  • 完全合法。数组只能在文件中按名称访问;如果文件中的某些函数(例如my_function())使指针可用,则可以通过指针访问它。这是 C 中经过深思熟虑的设计特性。(您甚至可以通过返回指向函数的指针来使指向静态函数的指针可用。)

标签: c


【解决方案1】:

变量x 在myfile.c 之外不可见,但是因为它位于文件范围内,即它具有静态存储持续时间,它的生命周期仍然是整个程序。

所以在源文件之间返回指向静态数据的指针是有效的。

【讨论】:

    【解决方案2】:

    此代码不会是未定义的行为,因为即使在您的函数退出后,您的函数返回的指向 x 存储空间的指针仍将保持有效。换句话说,这不会产生当您返回指向本地分配的自动存储的指针时遇到的问题。

    直接返回此指针可能会遇到的一个问题是调用者可能不尊重x 的存储边界,并且访问超过my_function()+sizeof(x) 的内存。这可以通过提供读取和写入x 的函数而不返回指向它的指针来解决。

    注意:使用static 会使变量x 的名称无法访问,而不是其存储。这个想法是让其他模块定义自己的变量x,而不会造成名称冲突。

    【讨论】:

      【解决方案3】:

      “静态”变量有两种不同的作用。如果你将一个变量声明为静态within函数,那么即使在函数返回后,在函数内分配给它的内存仍然可以访问,例如:

      #include <stdio.h>
      
      char *func1()
      {
          static char hello[] = {"Hello, world!\0"};
          return hello;
      }
      
      char *func2()
      {
          char goodbye[] = {"Goodbye!\0"};
          return goodbye;
      }
      
      int main( int charc, char *argv[] )
      {
          printf( "%s\n", func1() );
          printf( "%s\n", func2() );
      }
      

      对 func1() 的调用是有效的,因为在函数内部声明的变量“hello”被设置为静态,所以即使在函数返回后它仍然可以访问。

      对 func2() 的调用是未定义的行为,因为一旦函数返回分配给“再见”的内存,就会返回给操作系统。一般会出现段错误,程序会崩溃。

      “静态”会做的另一件事是,当变量(或函数)在文件级别声明为静态时,该变量(或函数)将只能在该文件中访问。这是为了数据封装。

      所以如果我有 file1.c 和以下代码:

      static *char hello()
      {
          static char hi[] = {"Hi!\0"};
          return hi;
      }
      

      然后在 file2.c 我有:

      #include <stdio.h>
      
      extern char *hello(); //This lets the compiler know that I'm accessing a function hello() in another file
      
      int main( int charc, char *argv[] )
      {
          printf( "%s", hello() );
          return 0;
      }
      

      如果我编译它 gcc file1.c file2.c -o test

      编译器会抱怨找不到 hello()。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-04-09
        • 2011-01-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多