Prakhar
Prakhar

Reputation: 52

What is wrong with the following Code in C language?

I observed that in line int *x = malloc(sizeof(int)); this code is trying to convert a void* into a int* without using proper typecasting. So according to me answer should be option A. But in official GATE-2017 exam answer key, answer is given D. So am i wrong ? how ?

#include<stdio.h>
#include<iostream.h>
#include<conio.h>
#include<stdlib.h>

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

void main(){
    clrscr();
    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);
    getch();
}

In my opinion option D is only correct when int *x = (int *)malloc(sizeof(int)); is used.

Upvotes: 0

Views: 627

Answers (4)

Fatemeh Karimi
Fatemeh Karimi

Reputation: 987

you should never forget that a void * pointer can be assigned to all type of pointers. in IDEs like visual studio, you get a compile error if you do not perform casting while assigning a void * to <>. for example:

float *ptr = malloc(sizeof(float));//compile error in visual studio.

but if you compile it with GCC without typecasting, you won't get a compile error.

Upvotes: -1

Schwern
Schwern

Reputation: 164679

I observed that in line int *x = malloc(sizeof(int)); this code is trying to convert a void* into a int* without using proper typecasting.

There's more than a little debate about whether or not to cast malloc, but it's a stylistic thing. void * is safely promoted to any other pointer.

ISO C 6.3.2.3 says...

A pointer to void may be converted to or from a pointer to any incomplete or object type. A pointer to any incomplete or object type may be converted to a pointer to void and back again; the result shall compare equal to the original pointer.

Whatever you choose, pick one and stick with it.


The memory leak is here:

int *x = malloc(sizeof(int));
if(NULL==x) return;
x = assignval(x,0);
if(x){
    // Memory leak
    x = (int *)malloc(sizeof(int));

The first malloc points x at allocated memory. The second malloc can only happen if the first succeeded (if x is true). The pointer to the memory allocated by the first malloc is lost.

Using a new variable would fix the leak, keeping in mind that the code is nonsense.

int *x = malloc(sizeof(int));
if(NULL==x) return;
x = assignval(x,0);
if(x){
    int *y = malloc(sizeof(int));
    if(NULL==y) return;
    y = assignval(y,10);
    free(y);
}

As a side note, void main() is technically not a violation of the ISO C standard, it is "some other implementation-defined manner".

5.1.2.2.1 says:

The function called at program startup is named main. The implementation declares no prototype for this function. It shall be defined with a return type of int and with no parameters:

int main(void) { /* ... */ }

or with two parameters (referred to here as argc and argv, though any names may be used, as they are local to the function in which they are declared):

int main(int argc, char argv[]) { / ... */ }

or equivalent;) or in some other implementation-defined manner.

I'm guessing you're using a Windows compiler, that would be the "some other implementation". clang considers it an error.

test.c:8:1: error: 'main' must return 'int'
void main(){
^~~~
int
1 error generated.

Upvotes: -1

AnT stands with Russia
AnT stands with Russia

Reputation: 320381

There's no right answer among the choices offered.

The immediately obvious problems with the code, under assumption that the code is supposed to be written in standard C:

  • Standard library does not have <conio.h> header or <iostream.h> header.

  • void main() is illegal. Should be int main(). Even better int main(void)

  • clrscr(), getch() - standard library knows no such functions.

  • The second malloc leaks memory allocated by the first one (assuming the first one succeeds).

  • Result of second malloc is explicitly cast - bad and unnecessary practice.

Upvotes: 6

Marievi
Marievi

Reputation: 5001

The statement :

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

will not lead to compile error, as it declares x as a pointer to int and initializes it right afterwards. It did not have type void beforehand.

The statement :

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

causes a possible memory leak, as it reallocates the memory which is already allocated for x.


NOTE : However none of this answers is completely correct. This code will not compile for various reasons.

If this is your code, change :

void main()

to :

int main(void)

and also see why you should not cast the result of malloc.

Apart from that, clrscr(), getch(), <conio.h> and <iostream.h> are not recognized by standard library.

Upvotes: 0

Related Questions