I'm new to c language.
This is my code
char c[]="name";
char *p="city";
printf("\n 1. memory location of array in pointer is %u",p);
p=c;
printf("\n 2. memory location of array in pointer is %u",p);
it gives me output :
memory location of array in pointer is 177
memory location of array in pointer is 65518
now checkout the difference in memory allocation, when first time
char *p="city"
address in p is 177 and second time when
p=&c;
address in p is 65518. why?
I didn't get the address allocation to array. Normally when declare some variable in c, there address is something like 655... and at the time char *p, its different. Is there any specific reason for this.
I'm working on windows 7 32 bit operating system
My question is when
char *p="city"
address in p is 177. why?
Because the array name decays into pointer to first element when its assigned or passed (assigned to a variable of first element's address type).
p = c; // & is not needed, and not defined behavior
printf("%p\n", (void *)&p);
Gives you the address
there are different area in memory.
when you decalre a varaible it will declare in HEAP are .
ROM are where the containt of varible after declare ,cant change.
in your question char [], a array means varible it will go in HEAP.so 65432 or something.
2. char *p="name",is a string constant .the space for "name" will be declared in ROM area.so 772.you cant change "name" to "nass" .it may be or may not be.
LAST.space for each area given by virtual memory system .
ROM .LESS space --less bit addr
HEAP- LARGE SPACE so---large bit for addr(generally 4 byte in window 7).
Related
int main()
{
int *p;
printf("%p \n", &p);
printf("%p \n", p);
return 0;
}
By executing this code I am receiving the following output:
0x16b77f710
0x104683f4c
I expected to get the same memory address, because the &p id not referenced to any other variable.
Why i am getting two different memory address?
Thanks,
The pointer is a normal object having (in your case type of int *). It cant point to itself because the type of such pointer would have to be int **
*image stolen from internet.
A pointer is a variable like any other. It has an address, which is typically the address in memory where that variable sits.
Like any other variable, a pointer variable also has some data in it. For a pointer variable, that data is the address of some other variable, the variable at which the pointer points.
The address of a variable, and the contents of a variable, are two totally different things. They are almost never equal.
Try this program, in which I give your variable p something to point to:
int main()
{
int i = 5;
int *p = &i;
printf("p: %p, p's address: %p\n", p, &p);
printf("i: %d, i's address: %p\n", i, &i);
}
You should notice two things:
As in your first program, "p" and "p's address" will be different.
Whatever value you see for "p", it will be the same as "i's address".
The reason is that a pointer, when declared, does not point to itself by default. Simplified you can imagine it in such a way that a pointer occupies 2 memory cells. 1 memory cell has the virtual address where the pointer itself is located (&p in your case), the 2nd memory cell contains the virtual address where the pointer points to (p in your case).
Since memory cells retain their value when they are deallocated, the cell containing the destination address of your pointer still contains an obsolete value from another, already completed process.
You would have the same phenomenon if you declare a new integer variable and then print its value with printf, you will see that there will already be some number in the new variable that will appear completely random. This is also due to the fact that there is still an obsolete value in the corresponding memory cell.
Let assume there is random memory block for just understanding name it a. Now assume that p is pointing to that memory block.
&p returns the address of memory block where p is present.
p returns the address of memory block(&a) to the variable/memory block(a) which p is pointing.
So of course it will give different memory addresses.
I expected to get the same memory address, because the &p id not referenced to any other variable.
Pointer variables do not automatically point to themselves; if you don't explicitly initialize them, then their initial value will be indeterminate (or NULL, depending on how they are declared).
There's nothing magic about pointer variables - like any other scalar, they store some kind of value; it's just that in their case, that value is an address of another object.
If you really want p to store its own address, you'll have to do something like
p = (int *) &p;
The cast is necessary because the type of the expression &p is int **, and you can't assign a pointer value of one type to a variable of a different pointer type. But, pointers to different types are not guaranteed to have the same size, representation, or alignment. On modern commodity hardware like x86 you can probably count on int * and int ** having the same size and representation, just be aware that doesn't have to be the case everywhere.
What is the difference between the two, a ptr pointing at a variable and a ptr pointing at memory? I know a pointer is a variable that holds the memory address of a variable. So... A ptr pointing at a variable holds the address of that variable whereas a ptr pointing at memory is directly pointing at memory? The first somehow still holds some information about the initial variable whereas the later only knows an address?
EDIT: I didn't mean for this question to cause so much controversy and I'm not entirely sure why it's getting downvoted. I'm just trying to understand pointers... After doing some reading on the linked 'duplicate' it is my understanding that a ptr pointing to a variable always references that variable, cannot be reassigned, and cannot point to other pointers, and share an address with the variable. Memory pointers can point to NULL, can be reassigned, can point to other pointers, and have their own memory address. Are these true for C or only C++
A pointer is a variable whose value is an address in memory. The pointer also knows the type of whatever it's pointing to (or else it's a void*).
Basically that's all there is to it. There is no fundamental distinction between a "pointer that points to a variable" and a "pointer that points to memory". Whatever the pointer points to is in memory in any case. Whether the pointer points to a char variable, or a double variable, or an object, it's always simply pointing to the memory location where that char/double/object is stored.
Here's the way I see it, and I'll go by example.
In C, a pointer variable can be declared as:
char* p;
Then you can reserve stack memory for your program via a char array like so:
char buffer[5000];
You can then make the pointer reference this memory block like so:
p=buffer;
Variables by default point to their own addresses in stack memory for fast access. If you want to assign a pointer to memory from the heap, you can use calloc() or malloc(). For example, this code:
char* m;
m=malloc(5000);
... allocates 5000 bytes of memory from the heap (aka extended memory). then when you make reference to that pointer, you're actually reading to and writing from RAM.
This prints the letter "A" to the same static memory location twice then reads it back:
char block[10];
char* p=block;
block[0]='A'; //write to 1st position of block memory
*p='A'; //write same value to 1st position of block memory again
char *r;
r=p;
printf("%c",*r);
And now the same program but this time using just memory from the heap:
char* block;
block=malloc(10);
char* p=block;
block[0]='A'; //write to 1st position of block memory
*p='A'; //write same value to 1st position of block memory again
char *r;
r=p;
printf("%c",*r);
free(block);
please note that i am still learning and some information might be wrong
ok for example lets make
int i = 5;
int *ptr = &i;
lets say memory address for those are
i = 0x0001
ptr =0x0002
in those memory address are
0x0001 = 0101 // this is 5 for binary
0x0002 = 0x0001 //this is the address of 'i'
so when ptr is called in these kind of ways u get these values
ptr = 0x0001 // the address stored in ptr
*ptr = 0101 // the * means whatever is at the address stored in ptr
if i had wrote like this
int i = 5;
int *ptr = *i;
then ptr will have whatever is at 'i'
i = 0x0001
ptr = 0101
so if i call ptr again in these ways
ptr = 0101
*ptr // this will not work cus 0101 is not a memory address
edit
Also on your edit u said "that a ptr pointing to a variable always references that variable, cannot be reassigned, and cannot point to other pointers, and share an address with the variable."
This is not true for C, a pointer can be reassigned whenever u want and can point to other pointers
Unless it was made as a
const int *ptr = &i;
Then the pointer can not be changed later
Also u said "memory pointers can point to NULL, can be reassigned, can point to other pointers, and have their own memory address"
This is true as I said above but there are no such thing as a memory pointer and a variable pointer, there is only pointer that can hold a memory address.
This question already has answers here:
Pointers - Difference between Array and Pointer
(2 answers)
Closed 9 years ago.
char* pointer;
char array[10];
I know that the memory of second one is already allocated in the buffer. But, I don't know how exactly pointer works in terms of memory allocation. How much space does pointer initially takes before it is allocated by the programmer with malloc or calloc? Additionally, if I initialize it like this
char* pointer;
pointer = "Hello World!";
If the memory isn't allocated before it's initialized with some random string size, how is this being initialized? Wouldn't there be any error involved?
I was just programming with pointers and arrays mechanically w/o really knowing how it works inside the computer. And, I thought I should understand this perfectly for better programming practice.
Pointer is just to store address of one variable. i.e, if you say char* it stores address of one character. like int i=9; means memory of sizeof(int) is reserved and labled as "i" inyour program. Like wise char* c; means memory of size(char*) is reserved and labled as "c"; in c="hello"; "h","e","l","l","o" got seperate "continous" memory allocated. and pointer c points to first char "H".
consider in memory HELLO is store before string "India".
"HELLOINDIA."
for char *c="HELLO"; c[5] returns I.
for char c[5]="HELLO"; c[5] is array out of bound error.
char array[10] ,
It will reserve memory of 10 bytes on stack frame of function in which you have declared it.
Whereas in char *ptr = "hello" ptr will get 4 bytes memory on stack in 32 bit O.S,also "hello" is string literal which will get stored on non-bss part of your executable,and ptr is pointing to it from stack frame.
This declaration:
char *pointer;
reserves sizeof(char *) bytes for the pointer value. No other memory is allocated.
This declaration:
char array[10];
reserves 10 bytes for the array.
In this case:
char *pointer;
pointer = "Hello World!";
You still have a single pointer (sizeof(char *) in size) that points to a string literal somewhere in memory - no other allocations are taking place. Storage for the string literal is worked out by your toolchain at compile time.
Pointers and arrays are completely different things. Any similarity and confusion between the two is an artifact of the C language.
A pointer is a variable which holds the location of another variable. An array (in C) is an aggregate of values of identical type, consecutively allocated in memory.
Arrays are accessed via arithmetic upon a pointer to the base element, [0]. If an expression which refers to an array is evaluated, the value which emerges is a pointer to element [0].
int array[10];
int *p = array; /* array expression yields pointer to array[0] */
int *q = &array[0]; /* q also points to same place as p */
The array notation in C is a sham which actually works with pointers. The syntax E1[E2] means the same thing as *(E1 + E2) (assuming that E1 and E2 are sufficiently parenthesized that we don't have to be distracted by associativity and precedence.) When we take the address of an element via &E1[E2], this is the same as &*(E1 + E2). The address-of and dereference "cancel out" leaving E1 + E2. Therefore, these are also equivalent:
int *r = array + 3;
int *q = &array[3];
Because array[i] and pointer[i] are both valid syntax, people in the newbie stage (mistaking syntax to be semantics) conclude that arrays and pointers are somehow the same thing.
Spend some time programming in an assembly language. In assembly language, you might define some storage like this:
A: DFS 42 ;; define 42 words, labelled as A.
Then use it like this:
MOV R13, A ;; address of A storage is moved into R13
MOV R1, [R13 + 3] ;; load fourth word, A[3]
R13 points to the storage. That doesn't mean A is a pointer. A is the name of the storage. Of course to use the storage, we need its effective address and so a reference to A resolves to that. When the code is assembled and linked, that MOV instruction will end up loading some numeric address into R13.
C is just a higher level assembly language. Arrays are like named storage which resolves to its effective address (being a pointer data type).
Arrays do not always resolve to their effective address. sizeof a calculates the size of an array a in bytes, whereas sizeof p calculates the size of the pointer data type p.
Another difference is that the name of an array cannot be made to refer to any place other than that array, whereas we can assign values to pointers:
array++; /* invalid */
array = &array[0]; /* invalid */
p = &array2[0]; /* valid */
p++; /* valid: point to the next element in array2 */
A pointer takes up whatever space is required to describe a memory location. In general (but not always), the size of a pointer is the same as the bit-size of the processor/OS/program-mode (e. g. 8 bytes for a 64-bit program on a 64-bit OS, 4 bytes on a 32-bit program, etc.). You can find this out using
sizeof (void *)
In the case of
char* pointer;
pointer = "Hello World!";
You'll have one pointer allocated in R/W memory, plus the space for the string (13 bytes, including the trailing null byte) in R/O memory, perhaps more if the next object in memory is aligned on better than a byte boundary). Note that the same R/O space would be allocated for
printf("Hello World!");
so that actually has nothing to do with the pointer. In fact, most optimizing compilers would notice that the two strings are exactly the same and only allocate it once in R/O memory.
I don't know how exactly pointer works in terms of memory allocation. How much space does pointer initially takes before it is allocated by the programmer with malloc or calloc?
pointer itself is just a data type, like int, char...etc.
it point to a memory address (or NULL).
it can be malloc, become a pointer point to a block of memory you ask.
you very likely mistaken that pointer = malloc, it's not.
when you define a pointer in c, e.g. char *c; or int *i it will reserve a memory equal to sizeof(char *) and sizeof(int *) respectively.
But the actual memory reserved depends on your system/OS, if it is 64-bit it will reserve 8 bytes, if it is 32-bit it reserves 4 bytes.
In case of declaring char *c = "Hello world";
the string "Hello world" can be stored any where in memory but here c points to first character of the string that is 'H'.
How can I get the address of a multidimensional static array?
For example, this is my array
char array[2][10] = {"word1", "word2"};
Is it possible to get the address to make me reference this array using a pointer like this?
char** pointer;
I tried &array or directly pointer = (char**)array; but it crashes at startup.
char **pointer means that a pointer is pointing to a pointer.
So *pointer is expected to be a pointer (e.g. 4-byte value which can be interpreted as an address).
This is not the case with your array: it is a contiguous area in memory (20 bytes).
So when you try to convert the array to char ** your application crashes.
It's not possible to do this conversion, char ** must point at a pointer.
"array" is the address of the array in memory but it is not a char**. While you can cast it, the application will crash if you try
printf("%s", pointer[1]);
because in your case is probably the same as
printf("%s", (char *)(0x00000031));
since pointer[1] means "the second 4 byte pointer (assuming x86) starting from 'array'".
pointer[0] MAY not crash but won't show "word1" either for the same reason.
You probably want (this is hard to remeber so i had to check online, hope it is correct):
char (*pointer)[10] = array;
Which is a pointer to an array of 10 chars. And if you use pointer[1] it now means "the second 10 chars block starting from 'array'".
If a pointer stores the address of a variable ... then from where do we get the pointer?
What I asked was that if we are using pointer directly, then there must be a location from where we get this pointer?
Yes, a declared pointer has its own location in memory.
In the example above, you have a variable, 'b', which stores the value "17".
int b = 17; /* the value of 'b' is stored at memory location 1462 */
When you create a pointer to that variable, the pointer is stored in its own memory location.
int *a;
a = &b; /* the pointer 'a' is stored at memory location 874 */
It is the compiler's job to know where to "get the pointer." When your source code refers to the pointer 'a', the compiler translates it into -> "whatever address value is stored in memory location 874".
Note: This diagram isn't technically correct since, in 32-bit systems, both pointers and int's use four bytes each.
Yes. Below I have an int and a pointer to an int and code to print out each one's memory address.
int a;
printf("address of a: %x", &a);
int* pA = &a;
printf("address of pA: %x", &pA);
Pointers, on 32bit systems, take up 4 bytes.
In C:
char *p = "Here I am";
p then stores the address where 'H' is stored. p is a variable. You can take a pointer to it:
char **pp = &p;
pp now stores the address of p. If you wanted to get the address of pp that would be &pp etc etc.
Look at this SO post for a better understanding of pointers.
What are the barriers to understanding pointers and what can be done to overcome them?
As far as your question goes, if I understand what you want, then, basically, when you declare a pointer, you specify an address or a numeric index that is assigned to each unit of memory in the system (typically a byte or a word). The system then provides an operation to retrieve the value stored in the memory at that address.
The compiler deals with translating the variables in our code into memory locations used in machine instructions.
The location of a pointer variable depends on where it is declared in the code, but programmers usually don't have to deal with that directly.
A variable declared inside a function lives on the stack or in a register, (unless it is declared static).
A variable declared at the top level lives in a section of memory at the top of the program.
A variable declared as part of a dynamically allocated struct or array lives on the heap.
The & operator returns the memory location of the variable, but unlike the * operator, it can't be repeated.
For example, ***i gets the value at the address **i, which is the value at address *i, which is the value stored in i, which the compiler figures out how to find.
But &&i won't compile. &i is a number, which is the memory location the compiler uses for the variable i. This number is not stored anywhere, so &&i makes no sense.
(Note that if &i is used in the source code, then the compiler can't store i in a register.)