in Programming in C edited by
35,231 views
86 votes
86 votes

Consider the following C code:

#include<stdio.h>
int *assignval (int *x, int val) {
    *x = val;
    return x;
}

void main () {
    int *x = malloc(sizeof(int));
    if (NULL == x) return;
    x = assignval (x,0);
    if (x) {
        x = (int *)malloc(sizeof(int));
        if (NULL == x) return;
        x = assignval (x,10);
    }
    printf("%d\n", *x);
    free(x);
}

The code suffers from which one of the following problems:

  1. compiler error as the return of $malloc$ is not typecast appropriately.
  2. compiler error because the comparison should be made as $x == \text{NULL}$ and not as shown.
  3. compiles successfully but execution may result in dangling pointer.
  4. compiles successfully but execution may result in memory leak.
in Programming in C edited by
by
35.2k views

4 Comments

edited by

Can anyone explain the flow of the program? I am confused about what exactly is assignval fun returning.

Edit: If anyone is doubting about what the fun is exactly doing and what is being returned by it

Watch this: 

https://www.youtube.com/watch?v=1iVQQCndUXU

This code might help: https://ideone.com/opzpIy

1
1

This might help. 

1
1

Only leads to memory leak, not dangling pointer

 

2
2

7 Answers

95 votes
95 votes
Best answer

Answer is D.  

Option A:  
 In C++  we need to do typecasting. C does automatic implicit typecasting. 

See the screenshot for C & C++ compilers below. C compiler is working fine but C++ compiler is giving error.

Option B: Null means address 0.  if $( a == 0)$    if $( 0 == a )$  There is no difference. 

Option C: Do it step by step, always $x$ is pointing to a valid memory location. Dangling Pointer means if it points to a memory location which is deleted(freed). So no dangling pointer.  http://www.geeksforgeeks.org/dangling-void-null-wild-pointers/

Option D: $x$ will loss the previous address it was pointing to. So it will result in memory leakhttp://www.geeksforgeeks.org/what-is-memory-leak-how-can-we-avoid/

Proof for Option A:

C Compiler:


edited by
by

20 Comments

@Arjun Sir, Can u verify this pls?
1
1

U compiled using C++ .......do it with C compiler ....it executes without any errors .....

2
2

void* is compatible with any type no need for type casting.

The Function malloc is most commonly used to attempt to ``grab'' a continuous portion of memory. It is defined by:

   void *malloc(size_t number_of_bytes)

That is to say it returns a pointer of type void * that is the start in memory of the reserved portion of size number_of_bytes. If memory cannot be allocated a NULL pointer is returned.

Since a void * is returned the C standard states that this pointer can be converted to any type. The size_t argument type is defined in stdlib.h and is an unsigned type.

So:


    char *cp;
		 cp = malloc(100);

attempts to get 100 bytes and assigns the start address to cp.

Also it is usual to use the sizeof() function to specify the number of bytes:


    int *ip;
		 ip = (int *) malloc(100*sizeof(int));

Some C compilers may require to cast the type of conversion. The (int *) means coercion to an integer pointer. Coercion to the correct pointer type is very important to ensure pointer arithmetic is performed correctly. I personally use it as a means of ensuring that I am totally correct in my coding and use cast all the time.

It is good practice to use sizeof() even if you know the actual size you want -- it makes for device independent (portable) code.

sizeof can be used to find the size of any data type, variable or structure. Simply supply one of these as an argument to the function.

reference:

http://users.cs.cf.ac.uk/Dave.Marshall/C/node11.html#SECTION001110000000000000000

see malloc specification in this link

0
0

@Ahwan plz tell me

#include<stdio.h>
int *assignval (int *x, int val) {
    *x = val;
    return x;
}

void main () {
    int *x = malloc(sizeof(int));
    if (NULL == x) return;
    x = assignval (x,0);
    if (x) {
        x = (int *)malloc(sizeof(int));
        free(x);// if free replaces to here
        if (NULL == x) return;
        x = assignval (x,10);
    }
    printf("%d\n", *x);
    
}

if I replace free to there , will that be a dangling pointer issue? and from where r u sure it is a memory leak?

0
0
@srestha  memory leak is due to the prev one. There are 2 malloc.  You are losing reference to that 1st memory location which is allocated. So memory leak.  
So D is correct for sure.

By the way dangling pointer issue exists in the last line I guess. Because that location is freed but x still points to it,  But after it we have nothing to execute, main function ends there. So pointer variable x will also be deleted immediately.
27
27

But In this line x= assignval(x,0) x(main x) will point to something which is not valid anymore because 

x(assignval local x) is local variable in assignval and goes out of scope after an execution of assignval() get over. and then again inside if statement because of x=assignval(x,0), x will point to some invalid, then why its not dangling?

0
0

@prachigupta   You do it again,   just rename that local variable x to x1 & do this qsn again.  assignval( ) is returning the address of that location which x was previously pointing to.

to assignval you passed the address which x is pointing to...
Then assignval returned the same address...so it is just overwritten. 

(It is not pass by value.  It is pass by reference)  Just rename that x to x1 if you are getting confused.

1
1

@prachigupta  That local variable x is deleted immediately after function returns. Right ? So why there will be dangling pointer issue ?
While u r second time calling it, u r passing address of new location to which x points to.

2
2

@Ahwan

 free(x);// when this last statement is executed,then after that x is not set to NULL.So can i say x is my dangling pointer.I agree that memory leak is abvious in this code.But can i say it has dangling pointer also?
2
2
When in assignval(int *x ,int val) function it return x what is that x ?

is it address store in x or value of of address stored in x?
0
0
Here the pointer *x was declared as int, and it was implicitly type cast. What if it was declared as void *x??

Will it be implicitly type cast like before?
0
0
memory leak here by first X allocation
0
0
I understand that in C, there is no compulsion to typecast while assigning the dynamic memory address to a pointer.

But we can’t de-reference the memory without knowing its datatype. (otherwise, it won’t know when to stop reading. )

But here in this code, In assignval function we are dereferencing without knowing the datatype of memory.

Wouldn’t that give any error ?
0
0

@Niraj raghuvanshi

“The Function malloc is most commonly used to attempt to ``grab'' a continuous portion of memory”

i think malloc does not used to allocate a contiguous portion of memory (actually it does but we cant say it directly) because using malloc will allocate a memory chunk as per the size provided by the user.

but calloc will guarantee that we will have a contiguous memory space allocated 

(and as it is in the name CAllOC = contiguous allocation)

 

1
1

In the code by @sresha above, @ahwan is saying it will cause dangling pointer issue on last line but I guess it will be on this line

int *assignval (int *x, int val) {
    *x = val;  /*<--*/
    return x;
}

as we are trying to dereference freed location and assigning value to it.

 

1
1

@SambhrantMaurya

I think void is not implicitly typecasted to other datatypes but it can be printed in any data type by typecasting it directly in printf or before.

1
1
edited by

Here, Memory leak happens as soon as this code is executed:-

if (x) {
        x = (int *)malloc(sizeof(int)); // Here is the memory leak as the
                       //previous space allocated by malloc gets lost.
        if (NULL == x) return;
        x = assignval (x,10);
    }

To fix this potential memory leak, we can add a "free" statement to deallocate the memory that was allocated for "x" when it is no longer needed. 

if (x) {
        free(x); //here free(x) should be added to avoid memory leak

        x = (int *)malloc(sizeof(int));

        if (NULL == x) return;

        x = assignval (x,10);   

    }

This will ensure that the memory allocated for "x" is properly deallocated when it is no longer needed, which will prevent a memory leak from occurring.

3
3
@Abhrajyoti00 In that case how will the printf work? And the memory leak is happening when malloc is called and the return value is assigned to x – which means the previous memory x is pointing to is getting leaked. So free(x) should have been done before this malloc.
2
2

@Abhrajyoti00

To fix this potential memory leak, we can add a "free" statement to deallocate the memory that was allocated for "x" when it is no longer needed. 

in this case won’t it leads to dangling pointer now?

bcoz after the $if$ statement , $x$ is getting derefrenced in the printf(). 

1
1
50 votes
50 votes

$\mathbf{{\color{Blue}Memory\,leak: }}$ 

What happens if some memory is heap allocated, but never deallocated? A program which forgets to deallocate a block is said to have a "memory leak" which may or may not be a serious problem. The result will be that the heap gradually fill up as there continue to be allocation requests, but no deallocation requests to return blocks for re-use. For a program which runs, computes something, and exits immediately, memory leaks are not usually a concern. Such a "one shot" program could omit all of its deallocation requests and still mostly work. Memory leaks are more of a problem for a program which runs for an indeterminate amount of time. In that case, the memory leaks can gradually fill the heap until allocation requests cannot be satisfied, and the program stops working or crashes. Many commercial programs have memory leaks, so that when run for long enough, or with large data-sets, they fill their heaps and crash. Often the error detection and avoidance code for the heap-full error condition is not well tested, precisely because the case is rarely encountered with short runs of the program — that's why filling the heap often results in a real crash instead of a polite error message. Most compilers have a 31 "heap debugging" utility which adds debugging code to a program to track every allocation and deallocation. When an allocation has no matching deallocation, that's a leak, and the heap debugger can help you find them.

is short: a way that memory which is no longer needed is not released or may happen when an object is stored in memory but cannot be accessed by the running code.


$\mathbf{{\color{Blue}Dangling\,pointer: }}$

 pointers that do not point to a valid object of the appropriate type or a pointer becomes dangling when the block of memory it points to is freed.

http://www.geeksforgeeks.org/dangling-void-null-wild-pointers/

http://cslibrary.stanford.edu/102/PointersAndMemory.pdf

https://en.wikipedia.org/wiki/Dangling_pointer

{
   char *dp = NULL;
   {
       char c;
       dp = &c;
   }
     /* c falls out of scope */
     /* dp is now a dangling pointer */
}
                

void func()
{  
    char *dp = malloc(A_CONST);
    free(dp);         /* dp now becomes a dangling pointer */
    dp = NULL;        /* dp is no longer dangling */
}

int *func(void)
{
    int num = 1234;
    /* ... */
    return &num;
}//after returning from func() mem freed 

edited by
by

3 Comments

After executing free(x); we delete the memory but  pointer 'x' point to same memory then why x is not dangling pointer?
1
1

(read yellow line) wiki: if the original program then dereferences the (now) dangling pointer, unpredicted behavior may result, as memory may now contain completely different data.

but in this program we are not going to use data from the object which reference previously was deallocated.

0
0
When you start analyzing the code, you will first encounter that memory leak is happening and every one is agree on that. If we talk about the dangling pointer then, as soon as we encountering their is dangling pointer, we are terminating the program and all the space allocated to that program will be reclaimed by OS. It is always a good practice to set pointer null after use of free. Still because here we are not using that pointer again so no undefined behavior will be invoked. So in this question we can not choose dangling pointer over the memory leak. Refrences- https://stackoverflow.com/questions/15432123/using-pointer-after-free https://en.cppreference.com/w/c/memory/free
2
2
39 votes
39 votes

Memory leak In simple words: you create memory dynamically and Forget to detele that memory.

So solution Make that Free(variable) (which contain the address of that variable)

Dangling Problem: You Freed the dynamically allocated memory, But still point to that memory.

So solution Make that variable= null (which contain the address of that variable).


#include<stdio.h>
int *assignval (int *x, int val) {
    *x = val;
    return x;
}

void main () {
    int *x = malloc(sizeof(int));   memory allocated dynamically to *x which point int data.
    if (NULL == x) return;   this case to chcek memory availiable or not if not then x= null is happen
    x = assignval (x,0);  this will make function call and assign *x= 0 and return addrees of same memory
    if (x) {               since x= memory address this condition is true
        x = (int *)malloc(sizeof(int));  New memory assign to x
        if (NULL == x) return;                this is true if memory availiable 
        x = assignval (x,10);                This assign memory location *x= 10.
    }
    printf("%d\n", *x);  print *x= 10 
    free(x);  we freed last allocated memory but not the memory which is assigned 1st time.
}

Dangling problem is arise if we use printf("%d\n", *x); after  free(x);

2 Comments

why dangling pointer problem is not arises here,although we did not assign pointer x as NULL.
0
0
because we are not accessing the memory after free(x), if we had a statement accessing that free memory by pointer then we will get the issue of the dangeling ptr, but after free(x) the program terminates, So although it’s true but can’t be chosen over memory leak here.

If this was a MSQ, then surely C and D both must be answer.
0
0
12 votes
12 votes

Option (D).

 malloc() return  a void type address(like 1201x) ,so no need for typecasting and now x contain a location . now x=assignval(x,0) is called that assign 0 on memory location pointed by x and return x(value of x, not value at address pointed by x). now again x contain same address(1201x).  if( x ) is evaluated to true because x contain a non zero value (1201x) and on x=(int*)malloc(sizeof(int)); assign a new location to x , so we lost the previous memory location because now we have no reference to that location and we can't free that location, so execution may result in memory leak.

points:

malloc() return a void type pointer so no need to typecasting.

x==NULL or NULL==x both are valid.

dangling pointer example

{
   char *dp = NULL;
   /* ... */
   {
       char c;
       dp = &c;
   } 
     /* c falls out of scope */
     /* dp is now a dangling pointer */
}

referance :

http://www.geeksforgeeks.org/what-is-memory-leak-how-can-we-avoid/ 

edited by

4 Comments

int *c = malloc(sizeof(int));

free(c);

If we only do this then 'c' is not a dangling ptr? But it is pointing to a memory location that is no longer allocated.
0
0
#include<stdio.h>
int *assignval (int *x, int val) {
    *x = val;
    return x;
}

void main () {
    int *x = malloc(sizeof(int));
    if (NULL == x) return;
    x = assignval (x,0);
    if (x) {
        x = (int *)malloc(sizeof(int));
        free(x);// if free replaces to here
        if (NULL == x) return;
        x = assignval (x,10);
    }
    printf("%d\n", *x);
    
}

if I replace free to there , will that be a dangling pointer issue?

0
0
Answer:

Related questions