Why the address of structure and next is not same? - c

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
struct node
{
int id;
struct node *next;
};
typedef struct node NODE;
int main()
{
NODE *hi;
printf("\nbefore malloc\n");
printf("\naddress of node is: %p",hi);
printf("\naddress of next is: %p",hi->next);
return 0;
}
The output is:
before malloc
address of node is: 0x7ffd37e99e90
address of next is: 0x7ffd37e9a470
Why both are not same?

TL;DR
Your code provokes Undefined Behavior, as already mentioned in Morlacke's Answer. Other than that, it seems that you're having problems on understanding how pointers work. See references for tutorials.
First, From your comments
When you say that there's memory allocated for ip in this case:
int i = 10;
int *ip;
ip = &i;
What happens is:
You declare an int variable called i and assign the value 10 to it. Here, the computer allocates memory for this variable on the stack. Say, at address 0x1000. So now, address 0x1000 has content 10.
Then you declare a pointer called ip, having type int. The computer allocates memory for the pointer. (This is important, see bellow for explanation). Your pointer is at address, say, 0x2000.
When you assign ip = &i, you're assigning the address of variable i to variable ip. Now the value of variable ip (your pointer) is the address of i. ip doesn't hold the value 10 - i does. Think of this assignment as ip = 0x1000 (don't actually write this code).
To get the value 10 using your pointer you'd have to do *ip - this is called dereferencing the pointer. When you do that, the computer will access the contents of the address held by the pointer, in this case, the computer will access the contents on the address of i, which is 10. Think of it as: get the contents of address 0x1000.
Memory looks like this after that snippet of code:
VALUE : 10 | 0x1000 |
VARIABLE : i | ip |
ADDRESS : 0x1000 | 0x2000 |
Pointers
Pointers are a special type of variable in C. You can think of pointers as typed variables that hold addresses. The space your computer allocates on the stack for pointers depends on your architecture - on 32bit machines, pointers will take 4 bytes; on 64bit machines pointers will take 8 bytes. That's the only memory your computer allocates for your pointers (enough room to store an address).
However, pointers hold memory addresses, so you can make it point to some block of memory... Like memory blocks returned from malloc.
So, with this in mind, lets see your code:
NODE *hi;
printf("\nbefore malloc\n");
printf("\naddress of node is: %p",hi);
printf("\naddress of next is: %p",hi->next);
Declare a pointer to NODE called hi. Lets imagine this variable hi has address 0x1000, and the contents of that address are arbitrary - you didn't initialize it, so it can be anything from zeroes to a ThunderCat.
Then, when you print hi in your printf you're printing the contents of that address 0x1000... But you don't know what's in there... It could be anything.
Then you dereference the hi variable. You tell the computer: access the contents of the ThunderCat and print the value of variable next. Now, I don't know if ThunderCats have variables inside of them, nor if they like to be accessed... so this is Undefined Behavior. And it's bad!
To fix that:
NODE *hi = malloc(sizeof NODE);
printf("&hi: %p\n", &hi);
printf(" hi: %p\n", hi);
Now you have a memory block of the size of your structure to hold some data. However, you still didn't initialize it, so accessing the contents of it is still undefined behavior.
To initialize it, you may do:
hi->id = 10;
hi->next = hi;
And now you may print anything you want. See this:
#include <stdio.h>
#include <stdlib.h>
struct node {
int id;
struct node *next;
};
typedef struct node NODE;
int main(void)
{
NODE *hi = malloc(sizeof(NODE));
if (!hi) return 0;
hi->id = 10;
hi->next = hi;
printf("Address of hi (&hi) : %p\n", &hi);
printf("Contents of hi : %p\n", hi);
printf("Address of next(&next): %p\n", &(hi->next));
printf("Contents of next : %p\n", hi->next);
printf("Address of id : %p\n", &(hi->id));
printf("Contents of id : %d\n", hi->id);
free(hi);
return 0;
}
And the output:
$ ./draft
Address of hi (&hi) : 0x7fffc463cb78
Contents of hi : 0x125b010
Address of next(&next): 0x125b018
Contents of next : 0x125b010
Address of id : 0x125b010
Contents of id : 10
The address of variable hi is one, and the address to which it points to is another. There are several things to notice on this output:
hi is on the stack. The block to which it points is on the heap.
The address of id is the same as the memory block (that's because it's the first element of the structure).
The address of next is 8 bytes from id, when it should be only 4(after all ints are only 4 bytes long) - this is due to memory alignment.
The contents of next is the same block pointed by hi.
The amount of memory "alloced" for the hi pointer itself is 8 bytes, as I'm working on a 64bit. That's all the room it has and needs.
Always free after a malloc. Avoid memory leaks
Never write code like this for other purposes than learning.
Note: When I say "memory alloced for the pointer" I mean the space the computer separates for it on the stack when the declaration happens after the Stack Frame setup.
References
SO: How Undefined is Undefined Behavior
SO: Do I cast the result of malloc
SO: What and where are the stack and heap?
Pointer Basics
Pointer Arithmetic
C - Memory Management
Memory: Stack vs Heap
Memory Management
The Lost Art of C Strucutre Packing will tell you about structures, alignment, packing, etc...

You have no malloc here.
hi pointer points to something undefined.
hi->next the same.
About the question. Why they should be?
I think you do not understand pointers.

because next is a pointer type and it is pointing to 0x7ffd37e9a470.
if you print the address if next &(hi->next), you can see both hi and hi->next has a difference of 2 (because of int id is the first element).

Related

Variable Pointer vs Memory Pointer

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.

Pointer To Structure: Understanding Element Addressing

So I have this structure:
typedef struct my_structure_s{
uint32_t* label;
uint32_t* data_1;
uint32_t* data_2;
} my_structure_t;
Ultimately, I am working towards allocating a single large block of memory, and moving the pointers to point towards appropriate places in the large block of memory. This block will be big enough so that I can have room for N1 and N2 elements for data_1 and data_2, where N1 and N2 are calculated in the program.
Actually, I am going to have a few of these structures, and I want to eventually point all of them to proper places in this block. I know how to move the pointers to point to the correct places, but I am having trouble understanding where the inner pointers get created in memory.
For instance I define:
my_structure_t* my_struct = malloc( sizeof(my_struct) );
my_structure_t example_struct;
my_struct = &example_struct;
Now I want to see the relative addresses, so I write:
printf("Base Address: %p\n", &my_struct);
printf("First Element: %p\n", &(my_struct->label));
printf("Difference: %x\n\n", (uint32_t)&(my_struct->label) - (uint32_t)&my_struct);
For some reason, the difference is a negative value! Why? Yes I am using a 32 bit kernel. Shouldn't the first element be next to, but further down, the heap? Also, why is the memory difference not 0x4 but instead -0x8? I think everything should be aligned...seeing how its a structure of repetitions of the same data type...and that data type has a sizeof() of 4.
Second, what if I don't point the pointer to an instance of a structure? Eg what if I do:
my_structure_t* my_struct_2;
my_structure_t* big_pool = malloc( sizeof(my_structure_t) );
my_struct_2 = big_pool;
printf("Base Address: %p\n", &my_struct_2);
printf("First Element: %p\n", &(my_struct_2->label));
printf("Difference: %x\n", (uint32_t)&(my_struct_2->label) - (uint32_t)&my_struct_2);
Here, the values are totally wacky. Once, I got a difference of 0x49f02aac. Where then is the actual label pointer placed in memory? In this case, how can I make sure the address of the label pointer itself is right after the base address, without pointing the base pointer to a normal structure instance? Can it be assigned somehow?
Ie, if I were to point the label pointer somewhere after creating the structure pointer, where would the label pointer itself be stored? How can I make sure that all of these inner pointers get stored, in the same sequence as in the definition, right after the base pointer?
Yes yes, I could have possible defined data_1[MAX_N1] or some other work around like that, then just defined an array of structure pointers, and assigned each one a fixed memory size, but I didn't. There are various reasons. Please stick with the questions I am asking.
Thanks!
First, malloc() do not allocate pointers, it allocates memory for your struct, and then it returns a pointer to it. It is perfectly possible to have an uninitialized pointer, or a pointer pointing nowhere (NULL).
Second, in C there are three types of variables, regarding to allocation:
Static variables (globals). They exist all the time the program is running.
Automatic variables (locals). They exist as long as the code block containing them is running.
Dynamic variables (malloc). They exists until they are freed.
With that in mind your examples:
my_structure_t* my_struct = malloc( sizeof(my_struct) );
my_structure_t example_struct;
my_struct = &example_struct;
The first structure is dynamic, the second one is automatic. Then you make the pointer point to the automatic one. Remember, you can have pointers to anything. The dynamic variable is lost (leaked).
printf("Base Address: %p\n", &my_struct);
printf("First Element: %p\n", &(my_struct->label));
That is tricky: my_struct is a pointer, but you are getting its address, so what you get is the address of the automatic variable my_struct of type pointer.
The -8 happens because you are comparing the addresses of two local variables: the local pointer my_struct and the member label of the local structure variable example_struct. And those just happen to be so layout in memory.
Try instead:
printf("Base Address: %p\n", (void*)my_struct);
printf("First Element: %p\n", (void*)&(my_struct->label));
(BTW: it is always a good idea to cast to (void*) when printf("%p").
The other example has a similar error: do print the address of the structure or the value of the pointer, but not the address of the pointer.
my_struct is a pointer to a my_structure_t. There are no guarantees about where the pointer is in relation to the object it points to.
I beleive what you are trying to test, based on your comments about the memory location is
printf("Base Address: %p\n", my_struct);
printf("First Element: %p\n", &(my_struct->label));
printf("Difference: %x\n\n", (uint32_t)&(my_struct->label) - (uint32_t)my_struct)
Notice the removal of & before my_struct in 2 places compared to your code.
In answer to the actual question you asked
Also, why is the memory difference not 0x4 but instead -0x8?
Either sizeof(my_structure_t*) is 8, or the compiler decided that example_struct should be 8 byte aligned, and added padding when adding thee variables to your stack.

The following C program regarding pointers is not working

#include<stdio.h>
int main(void)
{
int *pc;
*pc=100;
printf("\n Address of Pointer : %d",pc);
printf("\n Contents of Pointer : %d",*pc);
}
When I run the code in eclipse, it is saying "Pointers.exe has stopped working". What is the error?
Assigning a value to *pc is particularly dangerous. If pc contains the valid memory address , then the assignment
*pc = 100;
will attempt to modify the data stored at that address.
If the location modified by this assignment belongs to the program, it may behave erratically; if it belongs to operating system, the program will most likely crash.
Your compiler should raise a warning that pc is uninitialized.
Change it to:
int a;
int *pc;
pc = &a;
*pc = 100;
Your pc pointer was not initialized in your program.
Moreover the way your are printing a pointer value is incorrect, use this:
printf("\n Address of Pointer : %p", (void *) pc);
You forgot to point pc to somewhere useful. When you write
int *pc;
The compiler creates a pointer for you. The pointer points somewhere in memory, and you have no way of knowing where. Chances are, it points to a bad place in memory. When you overwrite it with *pc=... you overwrite a place in memory that shouldn't be overwritten.
So you need to have pc point somewhere.
int a, *pc=&a;
will do the trick. Now the compiler prepares an int for you then and you point pc to it. That way, when you write through the pointer, nothing bad will happen - you're writing on an area of memory that you know is safe.
Another way to initialize pc is like so:
int *pc = (int*)malloc(sizeof(int)); // Allocate an integer on the heap
Now *pc=100; will also work. Just don't forget to free(pc) when you're done.
You have:
int *pc;
*pc=100;
When you define the pointer to integer pc above, this pointer is not initialized, so it points to some memory that you have not allocated and you have not the right to access.
So your executable is crashing.
Just use a valid pointer, e.g. you can allocate some heap memory using malloc(sizeof(int)) (and later release it using free()), or just use stack-based memory for local automatic variables, e.g.:
/* An integer stack-allocated variable */
int n = 64;
/* Pointer to that integer */
int * pn = &n;
/* Change its value */
*pn = 100;
Moreover, to print an address, considering using the %p specifier for printf().
e.g.:
#include <stdio.h>
int main(void)
{
int n = 64;
int *pn = &n;
printf("n (before): %d\n", n);
*pn = 100;
printf("n (after): %d\n", n);
printf("Address of n: %p", (void *)pn);
return 0;
}
Output:
n (before): 64
n (after): 100
Address of n: 003AF7CC
Pointers need to POINT! A pointer is a variable that contains the adress of another variable.
int *pc;
This pointer contains some garbage value. Who knows what was in that memory before. The adress that it's pointing to could be an adress of memory that is occupied by another program. You need to assign a valid adress to a pointer if you want to change the value in that adress.
If you want to calculate sum of all the members of an array you would have to initialize the variable sum to 0 because it could contain other values.
The same is with pointers. They have to contain a valid adress of a variable if you want to modify the value.
Your program would work if you comment line *pc = 100;. You can display the adress of an uninitialized pointer but the program will crash if you try to change the value in that adress.

Address allocation for array and pointer to array in c

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).

Variation in Pointer address values

I tested a small program which is written below.My question is why there is a 12 bytes difference between the pointer to a value and a pointer to the first pointer.But if you look at other pointer addresses there is only a difference of 8 bytes every time.I executed this program multiple times and always I see this difference.Can anyone explain me what could be the reason?Thanks in advance..
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
int val;
int *ptr;
int **ptrptr;
int ***ptrptrptr;
int ****ptrptrptrptr;
int *****ptrptrptrptrptr;
val=10;
ptr=&val;
ptrptr=&ptr;
ptrptrptr=&ptrptr;
ptrptrptrptr=&ptrptrptr;
ptrptrptrptrptr=&ptrptrptrptr;
printf("Value-%d\n",val);
printf("Value address - %d\n",ptr);
printf("Pointer address - %d\n",ptrptr);
printf("Pointer Pointer Address -%d\n",ptrptrptr);
printf("Pointer Pointer Pointer Address -%d\n",ptrptrptrptr);
printf("Pointer Pointer Pointer Pointer Address -%d\n",ptrptrptrptrptr);
return 0;
}
The results are:
Value-10
Value address - -1308521884
Pointer address - -1308521896
Pointer Pointer Address --1308521904
Pointer Pointer Pointer Address --1308521912
Pointer Pointer Pointer Pointer Address --1308521920
It's just the stack layout your compiler chose, f.e. it could be for alignment reasons. Things would most likely still work with other layouts.
Side note, you should use %p to print addresses.

Resources