Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing pointer to local variable to function: is it safe?

Tags:

For example:

void func1(){
    int i = 123;
    func2(&i);
}
void func2(int *a){
    *a = 456;
}

When func1 calling func2, a pointer to local variable is passed to func2 -- the pointer is pointed to the stack. Is this safe for the rules of C?

Thanks.

like image 761
Albert Zhang Avatar asked Feb 17 '15 07:02

Albert Zhang


People also ask

What happens if you pass a pointer to a function?

Pass-by-pointer means to pass a pointer argument in the calling function to the corresponding formal parameter of the called function. The called function can modify the value of the variable to which the pointer argument points. When you use pass-by-pointer, a copy of the pointer is passed to the function.

Is it unsafe for a function to return a local variable by reference?

Any use of a pointer with such a value is invalid. It is dangerous to have a dangling pointer like that as pointers or references to local variables are not allowed to escape the function where local variables live; hence, the compiler throws an error.

Why should one never return a pointer to something that is stack allocated?

Because it will cause undefined behavior in your program. Show activity on this post. If you return a pointer to a local variable once the function returns it is out of scope. From then on it is undefined behavior if you access the returned pointer.

Can we pass pointer to function in C?

C programming allows passing a pointer to a function. To do so, simply declare the function parameter as a pointer type.


2 Answers

The scope of i is func1 and it outlives the call to func2. So it is perfectly safe.

like image 80
juanchopanza Avatar answered Oct 26 '22 03:10

juanchopanza


As stated in most of the answers before, it is perfectly safe to pass the pointer to func2() in your special case.

In a real world piece of software however, I consider this harmful as you don't have control on what func2() is doing with your variable. func2() may create an alias to its parameter to use it asynchronously at a later point in time. And at that time, the local variable int i may be gone when this alias is used later.

So from my point of view passing a pointer to a local (automatic) variable is extremely dangerous and should be avoided.

You may do so if you declare the variable in func1() as static int i;

In that case, it is ensured, that the memory for i won't get recycled and overwritten. However you will need to setup some Mutex locking for access control to this memory in a concurrent environment.

To illustrate this problem here is some code I just stumbled in yesterday while doing software testing at my customer. And yes, it crashes...

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;
}

In this case, the data in the DataBuff is long gone when the pointer in ASyncQueue.CommandArray[ASyncQueue.NextFreeEntry].BufferPtr is used to store the data to the EEPROM.

To fix this code, it is at least necessary to declare static UINT8 DataBuff[25]; Additionally, it shall be considered to also declare static valueObj_t NVMemObjas we don't know what the called function is doing with that pointer.

To put it briefly: TL;DR

Even though it is legal in the C-language I consider it as harmful to pass pointers to automatic variables in a function call. You never know (and often you don't want to know) what exactly the called function does with the passed values. When the called function establishes an alias, you get in big trouble.

Just my 2 cents.

like image 26
opt12 Avatar answered Oct 26 '22 02:10

opt12