While running the following program in GCC, i'm very much screwed.
main()
{
char *ptr1;
char arr[1];
int i;
char *ptr2;
ptr1 = (char *)malloc(1);
ptr2 = (char *)malloc(1);
printf("\n & ptr1 : %u\n", &ptr1); /* I got outputs
like, 000053
printf("\n address of arr : %u\n", arr); /* shows 000052
printf("\n address of i : %u\n", &i); /* shows 000045
printf("\n & ptr2 : %u\n", &ptr2); /* shows 000041
}
Here's a corrected version of your program:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char *ptr1;
char arr[1];
int i;
char *ptr2;
ptr1 = malloc(1);
ptr2 = malloc(1);
printf("&ptr1 = %p\n", (void*)&ptr1);
printf("arr = %p\n", (void*)arr);
printf("&i = %p\n", (void*)&i);
printf("&ptr2 = %p\n", (void*)&ptr2);
return 0;
}
What I've done:
You're calling printf(), so the "#include <stdio.h>" is mandatory.
You're calling malloc(), so the "#include <stdlib.h>" is mandatory.
(Well, not *quite*; there are other ways to acheive the same
effect, but there's absolutely no point in using them. The
"#include" is the right way to do this.
Don't cast the result of malloc(). Doing so can mask certain errors,
such as omitting the required "#include <stdlib.h>" or incorrectly
using a C++ compiler to compile C code.
A good pattern for using malloc() is:
ptr = malloc(sizeof *ptr);
or, if you want to allocate an array:
ptr = malloc(COUNT * sizeof *ptr);
I've used the simpler "malloc(1)" here since you're only allocating a
single character (and sizeof(char) is 1 by definition). But if you're
going to be changing the code in the future, the lines:
ptr1 = malloc(1);
ptr2 = malloc(1);
should probably be written as:
ptr1 = malloc(sizeof *ptr1);
ptr2 = malloc(sizeof *ptr2);
The way to print a pointer value with printf is to convert it to void*
(one of the few cases where a cast is correct and necessary) and use
the "%p" format. The result of the "%p" format is
implementation-specific; it can be a number in hexadecimal, decimal,
octal, or even something other than a number. On the implementations
I use, it's a hexadecimal number corresponding to the representation
of the address. But remember that addresses *are not* numbers;
they're addresses.
I don't know why you called malloc(). You allocate one byte each for
ptr1 and ptr2 to point to, but you never use that allocated memory.
(You're printing the addresses of the pointer objects themselves,
*not* the addresses of what they point to.) If you are going to use
the allocated memory, you should *always* check the result of
malloc(); it returns a null pointer value on failure. (There's not
always a good way to handle this failure, but even aborting the
program with an error message is likely to be better than blindly
ignoring the problem.)
**Why the memory is allocated from bottom to top?? ( in the order
ptr2, i , arr, and ptr1)
Why not? Who cares?
It's the compiler's job to worry about where and how variables should
be allocated. It does this so you don't have to. It will allocate
local variables in whatever way the compiler's author decided made the
most sense. There may or may not be a consistent order. There may or
may not be gaps to allow for alignment. There *will* be a unique and
valid address for each declared variable, and that's really all you
need to know. If you write code that depends on the details of how
things are allocated, that code is non-portable, and it will break
when you try it with another compiler.
You're likely to find the comp.lang.c FAQ illuminating; it's an
excellent resource, thanks to a lot hard work by Steve Summit. It's
at <
http://www.c-faq.com/>. Don't expect to be able to read the whole
thing in one sitting. If you like, you can start by reading bits and
pieces of it -- and you should always check it before posting a
question here.
But the FAQ is a set of answers to specific questions, not a tutorial.
You should also have a good book or other C tutorial. K&R2 (Kernighan
& Ritchie, _The C Programming Language_, 2nd edition) is generally
acknowledged to be the best tutorial, but it helps to have some
programming experience. For other resources, see the FAQ.