Reputation: 81
I faced a question in an interview of a company, and I cannot figure out the reason about the answer.
void newArray(int* local, int size)
{
local = (int*) malloc( size * sizeof(int) );
}
int main() {
int* ptr;
newArray(ptr, 10);
}
Ans: This would cause memory leak and the program is not correct.
Does anyone know why this code cannot work?
Upvotes: 2
Views: 512
Reputation: 3688
You lose the reference to the malloced memory. This should be Ok.
void newArray(int** local, int size)
{
*local = (int*) malloc( size * sizeof(int) );
}
int main(c,v) char **v; {
int* ptr;
newArray(&ptr, 10);
/* Do something with ptr? */
free(ptr);
}
Upvotes: 3
Reputation: 310930
For starters this program
void newArray(int* local, int size)
{
local = (int*) malloc( size * sizeof(int) );
}
int main() {
int* ptr;
newArray(ptr, 10);
}
demonstrates that who asked the question in the interview is not strong himself as a C programmer.
First of all, according to the C Standard, function main
without parameters shall be declared like
int main( void )
Secondly there is not any reason to declare the second parameter of the function newArray
as having the type int
instead of the type size_t
because the standard function malloc
used in the function has a single parameter of the type size_t
.
Otherwise the function should check that the argument passed to the function is not a negative value.
As for the question then function parameters are its local variables. They are initialized by the supplied arguments. You can imagine the function definition and its call the following way
newArray(ptr, 10);
// ...
void newArray( /* int* local, int size */ )
{
int *local = ptr;
int size = 10;
local = (int*) malloc( size * sizeof(int) );
}
As you can see it is the parameter (that is a local variable) local
that is changed inside the function. The argument itself stays unchanged. Only the value of the argument is used to initialize initially the parameter. After exiting the function its local variables (including its parameters) are not alive and destroyed.
So the function indeed has a memory leak.
You should pass the argument by reference if you want that its value was changed in the function. For example
void newArray( int **local, size_t size )
^^^^^^^^^^^^^^^^^^^^^^^^
{
*local = (int*) malloc( size * sizeof(int) );
}
And the function should be called like
newArray( &ptr, 10 );
However a question arises what to do with the value of the pointer *local
before reassigning it. Whether there should be called the function free
before the call of malloc or not.
So a more clear function definition can look like
int * newArray( size_t size )
{
return malloc( size * sizeof( int ) );
}
In this case it is the client of the function who decides what he should do with his own pointer which he is going to reassign.
Upvotes: 3
Reputation: 223699
In C, all function parameters are pass by value. So when the local variable local
is modified inside of newArray
, the change is not visible outside of the function. So the memory pointer is lost and you have a memory leak.
To fix the leak, the function should accept the address of a pointer (i.e. a pointer-to-pointer), then dereference that pointer so that ptr
in main
is updated. You would then need to call free
to free the memory.
void newArray(int **local, int size)
{
*local = malloc( size * sizeof(int) );
}
int main() {
int* ptr;
newArray(&ptr, 10);
free(ptr);
}
Also, don't cast the return value of malloc
.
Upvotes: 8
Reputation: 121357
The pointer ptr
is passed by value (like everything else in C). So, assigning the return value of malloc
to local
changes only local variable, not ptr
in main()
.
As a result, there's no way to access the pointer returned by malloc()
once the function newArray
returns. Hence, it results in a memory leak.
It's similiar to:
void func(int x)
{
x = 42;
}
int main(void)
{
int y = 0;
func(y);
/* 'y' remains 0 */
}
Upvotes: 1
Reputation: 399723
It cannot work since it changes the value of an argument inside a function, but since C is call by value that has no relation to the value of the variable that was used as that argument outside the function.
In other words, &local
inside newArray()
is not the same as &ptr
in main()
; they're different variables so changing one has no effect on the other.
Upvotes: 3