Jhon Margalit
Jhon Margalit

Reputation: 559

Mysterious behavior of malloc() function in C

In the following code there is two int arrays being malloced in another function (I wanted to check if i can free ANY pointer, or only pointers which were locally malloced). Both of the arrays are linked in some way and I cant understand why?

#include <stdlib.h>
#define LEN 10

int* foo(int*, int);
void main()
{
    int* arr = (int*)malloc(sizeof(int) * LEN);
    int* arr2 = foo(arr, LEN);
    for (int i = 0; i < LEN; i++)
    {
        arr2[i] = i;
        printf("%d\t", arr2[i]);
    }
    printf("\n");
    for (int i = 0; i < LEN; i++)
    {
        printf("%d\t", arr[i]);
    }
    printf("\n");

    for (int i = 0; i < LEN; i++)
    {
        arr[i] = i+1;
        printf("%d\t", arr[i]);
    }
    printf("\n");

    for (int i = 0; i < LEN; i++)
    {
        printf("%d\t", arr2[i]);
    }
    free(arr2);
}

int* foo(int* arr, int n)
{
    free(arr);
    return (int*)malloc(sizeof(int) * n);
}

The output is:

0       1       2       3       4       5       6       7       8       9
0       1       2       3       4       5       6       7       8       9
1       2       3       4       5       6       7       8       9       10
1       2       3       4       5       6       7       8       9       10

Upvotes: 0

Views: 90

Answers (4)

AdamF
AdamF

Reputation: 2930

yor code encounters erros and you should concern to fix them if you want things to work properly:

int* arr = (int*)malloc(sizeof(int) * LEN);

calling malloc without check for the return value!

if(!arr){
    puts("heap allocation failure");
    abort();
}

in function foo:

return (int*)malloc(sizeof(int) * n);

the same issue! check malloc return. after returning from this function the arr pointer in main is pointing to released buffer!!

in this line:

printf("%d\t", arr[i]);

accessing dangling pointer, pointer that already freed by foo! this memory is not your. this will lead to sigmentation fault! or undefined behavior if you didnt receive the SIGSIGV signal.

Upvotes: 1

Eric Postpischil
Eric Postpischil

Reputation: 222679

malloc and free do not allocate and free pointers. They allocate and free space (regions of data storage).

That space is referred to by addresses (pointer values). After you call malloc and assign its return value to arr, arr points to the reserved space. When you pass that pointer value to foo and foo passes it to free, the space is no longer reserved.

When you call malloc in foo, it reserves space again. It may reserve the same space, overlapping space, or different space. When you use the value returned in this second call as a pointer, it accesses the currently reserved space.

When you access the leftover value in arr, your program accessed the previously reserved space. (That is not always what happens; once the space is freed, you should not use the old pointer anymore. The C implementation will not always treat that old pointer as valid, and your program can crash, use the old space, use different space, or exhibit other behaviors.)

Where arr and arr2 are declared and where malloc and free are called is irrelevant—the scopes of the pointers used to hold the address values are not related to the reservations of the space. The values of the pointers are what provide access to the space. Whether you pass a value up or down through routine calls, it still points to the same space.

Upvotes: 2

Kaushal8899
Kaushal8899

Reputation: 46

Here arr and arr2 both refers to same memory location.

Upvotes: -1

dbush
dbush

Reputation: 223882

After calling foo, the memory pointed to by arr has been freed. You then attempt to access the memory that arr had pointed to.

Attempting to use memory after it has been freed invokes undefined behavior.

Try working with just arr first, then call foo and just work with arr2.

Upvotes: 3

Related Questions