【问题标题】:What is the purpose of declaring the array as static in the function?在函数中将数组声明为静态的目的是什么?
【发布时间】:2013-12-30 16:44:55
【问题描述】:

我创建了一个函数(例如:fun())并从主函数中调用它。我还在函数中创建了一个数组,并将数组的基地址返回给主函数中的整数指针.如果数组在函数fun()中声明为静态,则数组元素在主函数中正确显示。如果没有,则打印一些垃圾值。但反之亦然。即decalring主函数中的一个数组,并通过传递基地址将其打印到另一个函数中。那么将数组声明为静态有什么用?正确的解释是什么?

【问题讨论】:

  • 如果返回自动变量或数组的地址,则行为未定义。您能否发布两个版本,在这种特定情况下更容易发表评论

标签: c arrays pointers static garbage


【解决方案1】:

如果一个对象在函数中被声明为静态,那么它本质上是一个全局且永久的,并且不会像其他局部变量一样每次调用函数时都重新初始化。

如果你有一个函数本地的非静态对象,并且你返回它的地址,那么当调用者对该地址执行某些操作时,该对象已经超出范围,因为你不再在被调用的函数,并且您的指针所指的内存区域中包含未定义的数据,无论您之前放了什么。如果对象是静态的,那么它不会超出范围。

如果您有一个位于main 的本地对象,并且您从main 调用一个函数并传递一个指向该对象的指针,那么就程序而言,该对象仍然存在,因为您仍然“在" main 函数,当你离开被调用函数的主体时会返回到它,所以引用那个内存区域没有问题。这与main 无关:从不同的功能尝试相同的事情。

顺便说一句,这些都与数组无关,整个讨论适用于任何类型的对象。

【讨论】:

  • 另外,最好指出即使static 变量存在,它在声明它的函数之外是不可见的。
  • @UchiaItachi true:请注意 OP(如果他回来阅读此内容),尽管 static 变量的 符号名称 在在声明它的函数中,包含变量的 内存 会持续存在,并且可以在所述函数之外合法访问。
【解决方案2】:

如果数组声明为静态,那么即使在函数调用执行后数组仍然存在,因此您可以访问数组的元素。

实际上,静态数组分配在不同的内存段中,而不是分配在函数堆栈帧中。所以就算函数调用结束也没关系,数组还在。

【讨论】:

    【解决方案3】:

    如果你不声明数组static,那么当你离开函数时,数组“消失”。实际上,您在函数中声明的所有不是static 的变量仅在函数执行时才存在。从函数返回后,变量被释放from the heap。这称为变量的“scope”,即代码中变量所在的区域。

    在您的情况下,您正在返回一个指针,该指针指向您的数组曾经所在的区域,当函数正在执行时,但到 main 使用指针时,数组曾经所在的区域已被覆盖.

    【讨论】:

      【解决方案4】:

      对象可以具有以下三种存储持续时间之一:自动、静态或动态。

      具有自动存储持续时间的对象在定义后立即为其分配存储,并且该存储仅在当前范围的持续时间内保留;一旦退出该范围,该对象将不复存在。例如:

      void foo( int x ) // storage for x is set aside here
      {
        int bar;        // storage for bar is set aside here
      
        if ( x > 0 )
        {
          int i;        // storage for i is set aside here
          ...
        }               // storage for i is released here
      }                 // storage for x and bar is released here
      

      变量i只存在于if语句的范围内; barx 只存在于函数的范围内。一旦函数退出,这些变量就不再存在,并且为它们分配的任何存储空间现在都可供其他人使用1

      具有静态存储持续时间的对象会在程序启动时为其分配存储空间,并且该存储空间会一直保留到程序退出。在文件范围(任何函数之外)或使用 static 关键字声明的任何内容都具有静态存储持续时间:

      void foo( int x )   // storage for x is set aside here
      {
        static int bar;   // storage for bar was set aside at program start
        ...
      }                   // storage for x is released here; storage for bar will
                          // be released when the program exits
      

      这就是你看到你所做的行为的原因;当数组未声明static时,函数退出后释放它的存储空间,其他人可以随意覆盖它。当您声明它static 时,该存储空间将一直保留到程序退出,因此其他人无法使用它。

      具有动态存储持续时间的对象使用malloccallocrealloc 手动分配,并一直保留到使用free 明确释放。


      1。在实践中,xbari 的存储通常在函数入口处留出并一直保留到函数退出,但逻辑上说你不能指望有i 的任何存储都超出了 if 语句的范围,这意味着任何指向i指针 在 if 语句之外都将无效。

      【讨论】:

      • 不是register变量(第4个)第一次和最后一次使用时的存储时间吗? (不一定要声明到块的末尾?)
      猜你喜欢
      • 2021-05-10
      • 2015-03-31
      • 1970-01-01
      • 1970-01-01
      • 2011-10-23
      • 2021-01-05
      • 1970-01-01
      • 1970-01-01
      • 2020-10-20
      相关资源
      最近更新 更多