I wish I knew what "safety" is supposed to mean here (I saw your comment that you got this from an interview, and that the interviewer did not explain what he meant by that).
There are only 4 reasons why a function should receive a pointer as a parameter:
- The function is meant to update the parameter;
- The parameter is an array expression, which is automatically converted to a pointer expression when passed as a function argument;
- The parameter is a very large
struct
or similar aggregate type, and creating a local copy is deemed too expensive;
- The parameter was created via
malloc
, calloc
, or realloc
.
None of these should apply to the snippets you posted. The "safest" option for them is to not use a pointer at all.
One "unsafe" aspect of using a pointer is that you may intend for the input to be read-only, but because you've been passed a pointer, you are able to modify the input. For those cases, you want to const
-qualify that parameter:
void foo ( const char *str ) // we cannot modify what str points to
{
...
}
Another "unsafe" aspect of using a pointer is accidentally (or deliberately) updating the pointer value itself to access memory you shouldn't:
while ( *ptr )
do_something_with( ptr++ );
You can mitigate against this by declaring the pointer as const
:
void bar( int * const ptr ) // we cannot update the value in ptr
This doesn't stop you from using the []
subscript operator, though:
while( ptr[i] )
do_something_with( ptr[i++] );
Now, if your interviewer was thinking of multiple threads or some machine-level issue with respect to interrupts or volatility, then maybe he has a point - if there's something that that can modify the thing ptr
points to outside of the current thread of execution's control, then yes, the second method is "safer" in that respect (the pointed-to value won't change in the middle of the computation).
However, if the code is multithreaded and ptr
can be modified in different threads, access to it should be synchronized via a mutex or something. If ptr
can be updated outside of your program's control, it should have been declared volatile
:
int power1( volatile int *ptr ) { ... }
int power2( volatile int *ptr ) { ... }