从函数返回指针作为静态变量
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 &r[0]
。
static
变量从程序开始就存在并在程序结束时被销毁——因此在main
之前和main
之后。要返回指向本地数据的指针,例如从函数返回,它必须是 static
,否则 - 正如您所说 - 您将访问已释放的数据,这是不允许的。
【讨论】:
以上是关于从函数返回指针作为静态变量的主要内容,如果未能解决你的问题,请参考以下文章