从函数返回指针作为静态变量

Posted

技术标签:

【中文标题】从函数返回指针作为静态变量【英文标题】:Returning pointers from function as static variable 【发布时间】:2016-03-02 14:03:31 【问题描述】:

我正在学习 C 和阅读 this

#include <stdio.h>
#include <time.h>

/* function to generate and retrun random numbers. */
int * getRandom( ) 

   static int  r[10];
   int i;

   /* set the seed */
   srand( (unsigned)time( NULL ) );

   for ( i = 0; i < 10; ++i) 
      r[i] = rand();
      printf("%d\n", r[i] );
   

   return r;


/* main function to call above defined function */
int main () 

   /* a pointer to an int */
   int *p;
   int i;

   p = getRandom();

   for ( i = 0; i < 10; i++ ) 
      printf("*(p + [%d]) : %d\n", i, *(p + i) );
   

   return 0;

文章解释说,由于在函数中声明的指针是局部变量,因此必须将其定义为“静态”。 (第 7 行,变量 r)

我担心三点。

首先,“static int r[10]”声明他们要创建一个大小为 10 的 int 数组。当它从 getRandom 函数以“return r”返回时,该函数实际上返回 r[10] 的第一个成员的地址,还是 指向 r[10] 的第一个地址的指针

其次,在main函数中,p = getRandom()表示将getRandom()返回的地址或指针赋值给指针p。尽管 r 会在 getRandom() 停止工作时立即发出声音,但地址应该已经分配给了 p。那么,为什么需要将其声明为静态?

或者getRandom()将地址返回给指向r[10]的指针,因此当消失时,p会指向空地址而不是r[10]?

或者,当 getRandom() 停止时,不仅指向 r 的指针,而且 r[10] 数组也会消失,所以它需要是静态的?

第三,没有malloc声明的任何函数中的变量都会被存储为堆栈内存是否正确?

【问题讨论】:

这是一个很长的问题。我建议阅读一本好的 C 编程书籍,使用警告和调试信息编译您的示例(gcc -Wall -Wextra -g,如果使用GCC...)并在调试器(gdb)中逐步运行您的示例并查询有趣变量的值 随着教程的进行,其中有一个可怕的错误。要了解我的意思,请连续拨打至少 3 次 getRandom() 并比较它发出的数字... 【参考方案1】:

getRandom() 返回指向r[10] 的第一个元素的指针。

引自N1256 6.3.2.1 左值、数组和函数指示符

3 除非它是 sizeof 运算符或一元 & 运算符的操作数,或者是 用于初始化数组的字符串字面量,具有“类型数组”类型的表达式是 转换为类型为“pointer to type”的表达式,该表达式指向 数组对象并且不是左值。如果数组对象有寄存器存储类,则 行为未定义。

如果r[10] 不是static,则数组将在从getRandom() 返回时消失,之后访问将调用未定义的行为

“在没有 malloc 的情况下声明的任何函数中的变量都将存储为堆栈内存”是不正确的。 C 中的任何变量都不需要存储为堆栈内存。通常,静态变量不存储在堆栈上,而具有自动存储持续时间的变量存储在堆栈上。

【讨论】:

我不认为在这种情况下引用标准是值得的或完全没有意义的。 那么,static 变量的存储位置不是标准规定的,它可能在堆栈上?【参考方案2】:

函数实际上返回的是r[10]的第一个成员的地址,还是r[10]的第一个地址的指针?

A:第一个成员的地址。

尽管 r 会在 getRandom() 停止工作时立即发出声音,....

答:不,static 变量不会进入程序堆栈内存(与局部变量不同)。它们在程序执行的整个过程中存在

第三,没有malloc声明的任何函数中的变量都会被存储为堆栈内存是否正确?

简而言之,是的。 OTOH,malloc()-ed 内存生命周期不受函数范围的限制。

【讨论】:

【参考方案3】:

文章解释说,由于在函数中声明的指针是 局部变量,因此必须将其定义为“静态”。 (第 7 行, 变量 r)

r 是整数数组,而不是指针。而local不必暗含static,这又是另一种意思。

函数实际上返回的是第一个成员的地址 r[10],还是指向r[10]首地址的指针?

它返回第一个成员的地址:当您键入return r 时会自动发生这种情况,这相当于更详细的return &amp;r[0]

static 变量从程序开始就存在并在程序结束时被销毁——因此在main 之前和main 之后。要返回指向本地数据的指针,例如从函数返回,它必须是 static,否则 - 正如您所说 - 您将访问已释放的数据,这是不允许的。

【讨论】:

以上是关于从函数返回指针作为静态变量的主要内容,如果未能解决你的问题,请参考以下文章

C语言指针 静态变量的调用

关于类中静态成员函数和静态成员变量的知识点

LR静态存储/动态存储/指针变量脚本说明

指针函数不可以返回局部变量地址解决

C言语指针变量作为函数参数

总结了一些指针易出错的常见问题