例如:
void func1(){
int i = 123;
func2(&i);
}
void func2(int *a){
*a = 456;
}
Run Code Online (Sandbox Code Playgroud)
当func1调用func2,一个指向局部变量传递到func2-指针指向堆栈.这对C的规则是否安全?
谢谢.
如之前大多数答案中所述,func2()在特殊情况下将指针传递到是绝对安全的。
但是,在实际的软件中,我认为这很有害,因为您无法控制func2()变量的操作。func2()可以为其参数创建别名,以在以后的某个时间点异步使用它。并且那时,int i稍后使用此别名时,局部变量可能会消失。
因此,从我的角度来看,将指针传递给局部(自动)变量是极其危险的,应避免使用。
你可以这样做,如果你在声明变量func1()作为static int i;
在这种情况下,可以确保i不会回收和覆盖用于的内存。但是,您将需要设置一些Mutex锁定,以便在并发环境中对此存储器进行访问控制。
为了说明这个问题,下面是我昨天在为客户进行软件测试时偶然发现的一些代码。是的,它崩溃了...
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;
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,DataBuff当使用指针输入ASyncQueue.CommandArray[ASyncQueue.NextFreeEntry].BufferPtr将数据存储到EEPROM 时,数据中的数据将消失。
要修复此代码,至少需要声明static UINT8 DataBuff[25];另外,还应考虑也声明,static valueObj_t NVMemObj因为我们不知道被调用函数对该指针的作用。
简而言之: TL; DR
即使在C语言中是合法的,我也认为在函数调用中将指针传递给自动变量是有害的。您永远不会(通常也不想)知道被调用函数对传递的值到底做了什么。当被调用函数建立别名时,您会遇到麻烦。
只是我的2美分。