user2933783
user2933783

Reputation: 81

Interview about malloc in function

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

Answers (5)

cleblanc
cleblanc

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

Vlad from Moscow
Vlad from Moscow

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

dbush
dbush

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

P.P
P.P

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

unwind
unwind

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

Related Questions