Why the below code is not printing the value 10? rather it crashes..
void foobar(int *a)
{
int *c;
c = *a;
printf("%d\n", *c);
}
int main(void)
{
int *b = (int *)malloc(sizeof(int));
*b = 10;
foobar(&b);
}
Why the below code is not printing the value 10? rather it crashes..
void foobar(int *a)
{
int *c;
c = *a;
printf("%d\n", *c);
}
int main(void)
{
int *b = (int *)malloc(sizeof(int));
*b = 10;
foobar(&b);
}
Try making these small changes.
#include <stdio.h>
#include <malloc.h>
void foobar(int *a) {
printf("%d\n", *a); /* what was C about? */
}
int main(void) {
int *b = malloc(sizeof(int));
*b = 10;
foobar(b); /* pass the pointer b, not the address of the pointer b. */
free(b);
}
At first you should include stdio.h
and stdlib.h
Second, your function declaration is incorrect. It should be
void foobar(int **a)
instead of
void foobar(int *a)
Because you are passing pointer to pointer.
The code misses to include <stdlib.h>
and most likley runs on 64 bit.
To fix it do:
#include <stdlib.h> /* for prototype of malloc() */
#include <stdio.h> /* for prototype of printf() */
void foobar(int ** a) /* Fixed wrong type. */
{
int * c = *a;
printf("%d\n", *c);
}
int main(void)
{
int * b = malloc(sizeof(*b)); /* Removed unnecessary and dangerous cast. */
if (NULL != b) /* Added error checking. */
{
*b = 10;
foobar(&b);
}
free(b); /* Added clean up. */
return 0; /* Added return (unnecessary from C99 on). */
}
#include <stdio.h>
#include<stdlib.h> //--------> ERROR 3: INCLUDE STDLIB FOR MALLOC() FUNCTION
void foobar(int *a)
{
int *c;
c = *a; //--------->ERROR 2 : C POINTS TO THE CONTENTS OF A POINTER
printf("%d\n", *c);
}
// SOLUTION 1 : KEEP FUNCTION PROTOTYPE SAME AND PASS B TO FOOBAR AND MAKE C POINT TO A.
// SOLUTION 2 : CHANGE FOOBAR'S PROTOTYPE TO FOOBAR(INT**A).
int main(void)
{
int *b = (int *)malloc(sizeof(int));
*b = 10;
foobar(b); //-------->ERROR 1 : PASSING THE ADDRESS OD A POINTER VARIABLE
solution 1 :foobar(b); in main and c=a;
solution 2 :foobar(int **a);
Crashed due to wrong argument type in void foobar(int *a)
It should have been void foobar(int **a)
Though for requirement just correct foobar(&b) => foobar(b)
Let's talk about types for a minute.
Given the declaration
T *p;
then the following are all true:
Expression Type Value
---------- ---- -----
p T * Address of the thing p points to
*p T Value of the thing p points to
&p T ** Address of the variable p
In main
, you declare b
as int *
. In foobar
, you declare both a
and c
as type int *
.
In the call to foobar
, you're using the expression &b
, which has type int **
; this doesn't match up with the type of a
(and should have resulted in a diagnostic from the compiler). What you're doing is passing the address of the variable b
to foobar
, which is not what you want; you want to pass the value contained in b
, which is the address of the memory you grabbed from the malloc
call. So if you change your call to foobar
to read
foobar(b);
the code should work as you expect.
A picture might help a bit. All of the addresses are pulled out of thin air, and are not meant to represent any real-world platform; assume big-endian representation as well:
Item Address 0x00 0x01 0x02 0x03
---- ------- ---- ---- ---- ----
heap memory 0x00800000 0x00 0x00 0x00 0x0a
b 0xfff78000 0x00 0x80 0x00 0x00
a 0xfff781c0 0x00 0x80 0x00 0x00
c 0xfff781c4 0x00 0x80 0x00 0x00
The call to malloc
allocates 4 bytes starting at address 0x008000000; after the assignment *b = 10
, those four bytes contain the value 0x0000000a.
b
, a
, and c
are all variables with auto
extent; all three contain the heap memory address as their value. The expressions *b
, *a
, and *c
should all evaluate to whatever's being stored at address 0x008000000; that is, the integer value 10
. &b
evaluates to the address of b
, or 0xfff78000.
As others have mentioned, don't cast the result of malloc
. It's not required (at least, not in C as of the 1989 standard; C++ and earlier versions of C are different stories), and under the 1989 standard it can suppress a useful diagnostic if you forgot to #include
stdio.h or otherwise don't have a declaration for malloc
in scope. The general form for a malloc
call is
T *p = malloc( sizeof *p * num_elements );
so in your case it would read
int *b = malloc( sizeof *b );
Note that you should always clean up after yourself, even for toy programs like this, so you'll want to add
free( b );
before you exit your program.