正如之前大多数答案所述,在您的特殊情况下,将指针传递给func2() 是完全安全的。
然而,在现实世界的软件中,我认为这是有害的,因为您无法控制 func2() 对您的变量所做的事情。 func2() 可以为其参数创建一个别名,以便在以后的时间点异步使用它。并且那个时候局部变量int i在以后使用这个别名的时候可能就没了。
所以从我的角度来看,将指针传递给本地(自动)变量是非常危险的,应该避免。
如果您将func1() 中的变量声明为static int i;,则可以这样做
在这种情况下,可以确保i 的内存不会被回收和覆盖。但是,您需要设置一些互斥锁,以便在并发环境中访问此内存。
为了说明这个问题,这里是我昨天在我的客户做软件测试时偶然发现的一些代码。是的,它崩溃了......
void func1()
{
// Data structure for NVMemory calls
valueObj_t NVMemObj;
// a data buffer for eeprom write
UINT8 DataBuff[25];
// [..]
/* Assign the data pointer to NV Memory object */
NVMemObj.record = &DataBuff[0];
// [..]
// Write parameter to EEPROM.
(void)SetObject_ASync(para1, para2, para3, &NVMemObj);
return;
}
void SetObject_ASync(para1, para2, para3, valueObj_t *MemoryRef)
{
//[..]
ASyncQueue.CommandArray[ASyncQueue.NextFreeEntry].BufferPtr = MemoryRef->record;
//[..]
return;
}
在这种情况下,当ASyncQueue.CommandArray[ASyncQueue.NextFreeEntry].BufferPtr中的指针用于将数据存储到EEPROM时,DataBuff中的数据早已不复存在。
要修复此代码,至少需要声明static UINT8 DataBuff[25];。此外,还应考虑声明static valueObj_t NVMemObj,因为我们不知道被调用的函数对该指针做了什么。
简单地说:
TL;DR
尽管在 C 语言中是合法的,但我认为在函数调用中传递指向自动变量的指针是有害的。您永远不知道(通常您也不想知道)被调用的函数对传递的值究竟做了什么。当被调用的函数建立别名时,你就麻烦了。
只要我的 2 美分。