Subash
Subash

Reputation: 43

Address behaviour with dynamic memory allocation in C

I wrote the following two codes and their outputs are given respectively.

Code 1:

#include<stdio.h>
int* allocate(int array, int value)
{
    int k[array];
    //int *k=(int *)malloc(array*sizeof(int));
    for(int i=0;i<array;i++)
    {
        k[i]=value;
        printf("%d ",k[i]);
    }
    printf("\n");
    return k;
}
int main(void)
{
    int *p=allocate(3,25);
    for(int i=0;i<3;i++)
        printf("%d ",p);
    return 0;
}

Output:

25 25 25
0 0 0

Code 2:

#include<stdio.h>
int* allocate(int array, int value)
{
    //int k[array];
    int *k=(int *)malloc(array*sizeof(int));
    for(int i=0;i<array;i++)
    {
        k[i]=value;
        printf("%d ",k[i]);
    }
    printf("\n");
    return k;
}
int main(void)
{
    int *p=allocate(3,25);
    for(int i=0;i<3;i++)
        printf("%d ",p);
    return 0;
}

Output:

25 25 25
12329552 12329552 12329552

I understand that in the first code, the data is allocated in the stack, and it would be cleared by the compiler once the return statement is executed. But I'm just printing 'p' and not '*p'. Why it shows 0? After all, pointer *p is declared within the main().

Kindly explain in simple terms. Thanks in advance.

EDIT 1: I'm adding a new code to make my question clear. Code 3:

#include<stdio.h>
int* allocateArray(int size, int value)
{
int arr[size];
for(int i=0; i<size; i++) {
arr[i] = value;
}
return arr;
}

int main(void)
{
    int* vector = allocateArray(5,45);
for(int i=0; i<5; i++) {
printf("%d\t", &vector[i]);
}
    return 0;
}

Output:

0 4 8 12 16

In the third code, I can't print vector[i] or *(vector+i). The compiler terminates the program.

The explanation of 0 and the pattern in the output of the third code is what all I need.

Upvotes: 0

Views: 87

Answers (1)

Veltas
Veltas

Reputation: 1013

In your answer you explain that you understand that you are returning a pointer to an array in allocate that ceases to exist before the pointer is assigned to p in main, and are wondering why a null pointer appears to be returned instead of a 'realistic' stack pointer, for instance.

Why is NULL allowed?

As explained in the comments, your compiler also knows that the pointer will not be valid by the time it is examined, and so can return a null pointer because of the following rule:

From ISO/IEC 9899:2011 Section 6.2.4:
The value of a pointer becomes indeterminate when the object it points to (or just past) reaches the end of its lifetime.

By indeterminate, it means the value of such a pointer will be unspecified or potentially a trap representation (which causes undefined behavior if read by any operation), which means a null pointer would be fine to return, as well as a pointer to another existing object, a pointer to no object, and a pointer value that could cause crashes or unexpected behavior in your program.

Why did the compiler pick NULL?

As for why the compiler implementation decided on a null pointer, possibly because it's a choice which is unlikely to silently break your program. A compiler will not usually impact performance to save you from yourself, but here it is at full liberty to optimize much of the preceding function away and simply return a null pointer that in a typical hosted environment will cause an immediate segfault if it is dereferenced, rather than allowing for the possibility of overwriting other objects in memory by trying to use the 'allocated' array.

Upvotes: 1

Related Questions