正如之前的大部分回答所述,对于您的特殊情况,在
func2()
中传递指针是完全安全的。
然而,在真实的软件中,我认为这是有害的,因为您无法控制
func2()
对变量的操作。
func2()
可能会创建一个参数的别名,以便在稍后的时间异步使用它。但是在此别名稍后被使用时,本地变量
int i
可能已经消失。
因此,从我的角度来看,传递指向本地(自动)变量的指针是极其危险的,应该避免。如果您在
func1()
中声明变量为
static int i;
,则可以这样做。
在这种情况下,可以确保不会回收和重写
i
的内存。但是,在并发环境中需要设置一些互斥锁来进行访问控制。
为了说明这个问题,这里是昨天我在客户那边做软件测试时遇到的一些代码。是的,它会崩溃...
void func1()
{
valueObj_t NVMemObj;
UINT8 DataBuff[25];
NVMemObj.record = &DataBuff[0];
(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
,因为我们不知道调用的函数对该指针做了什么。
简而言之:
总之
尽管在C语言中这是合法的,但我认为将自动变量的指针传递给函数调用是有害的。您永远不知道(通常也不想知道)调用的函数对传递的值做了什么。当所调用的函数建立别名时,问题就出现了。
这只是我的两分钱。