What will be the output of the program on a 32-bit machine (using GCC)? Explain.
#include<stdio.h>
int main() {
struct node {
int data;
struct node *link;
};
struct node *p, *q;
p = (struct node *) malloc(sizeof(struct node));
q = (struct node *) malloc(sizeof(struct node));
printf("%d, %d\n", sizeof(p), sizeof(q));
return 0;
}
The output shows
4, 4.
Is the above program related to structure member alignment padding and data packing?
No, you are just printing the size of the pointers. It's not related to the internal member layout of structures.
On a 32-bit system the stored addresses are always 32 bits big. If you're printing the size of a pointer you're basically just printing the size of the address it points to (32 Bit -> 4 Byte).
If you want to know the size of the struct do something like this:
struct node p;
struct node q = {4, &p};
printf("%zu, %zu\n", sizeof(p), sizeof(q));
Point 1 Use %zu format specifier to print the output of sizeof of type size_t .
Point 2 Note the type of p, it is struct node *, same as q.
So, essentially, sizeof(p) and sizeof(q) are exactly same as sizeof(struct node *), which, on your platform are 32 bit wide. As you're not considering a variable here, so the alignment and padding for the structure and members are neither relevant nor involved in this case.
That said, please see why not to cast the return value of malloc() and family in C.
No, it is not related to the structure member alignment padding and data packing.
Since it is a 32-bit machine the size of any pointer will be 4 bytes. Since p and q are of type struct node * i.e. pointer to struct node the result prints size of pointers p and q.
Related
I'm a C beginner, and I came across this code while trying to implement a linked list.
struct Node *ptr = malloc(sizeof(*ptr));
The Node struct looks like this:
struct Node {
int data;
struct Node *next;
};
I'm trying to understand the first line. It seems as if malloc(sizeof(*ptr)) already knows the contents of ptr. What exactly is happening on the left side and is it happening before malloc is called?
It seems as if malloc(sizeof(*ptr)) already knows the contents of ptr.
Actually, it doesn't. The sizeof operator doesn't actually evaluate its operand (unless it's a variable length array), it just looks at its type. This means that ptr isn't actually dereferenced and is therefore a safe operation.
Only use paranthesis with sizeof if there's a type you'd like to know the size of. If you have an expression, like *ptr, it's enough to write:
struct Node *ptr = malloc(sizeof *ptr); // <- no parenthesis
The expression *ptr dereferences the pointer so it becomes a struct Node and that's what the sizeof is returning the size for.
sizeofexpression - Returns the size, in bytes, of the object representation of the type of expression. No implicit conversions are applied to expression.
It's the same size you get if you do:
struct Node *ptr = malloc(sizeof(struct Node)); // <- parenthesis needed
but the first alternative is often preferable for clarity.
You need to allocate a memory for an object of the type struct Node declared like
struct Node {
int data;
struct Node *next;
};
So in the call of malloc you need to specify the size of the memory to be allocated for an object of this type. The function malloc returns a pointer to the allocated memory.
So you can write
struct Node *ptr = malloc( sizeof( struct Node ) );
On the other hand, the expression *ptr has the type struct Node. That is the declared pointer ptr has the pointer type struct Node * and dereferencing such a pointer like *ptr yields an expression of the type struct Node.
So you may rewrite the above record also like
struct Node *ptr = malloc(sizeof(*ptr));
because in this case sizeof( struct Node ) is equivalent to sizeof( *ptr ).
That is the compiler needs to know the type of the operand of the operator sizeof that to determine the size of an object of that type.
If the size of a structure pointer is 4 or say 8 bytes, how can it properly allocate the required memory for its data members in Dynamic Memory Allocation. This is my code:
#include<stdio.h>
typedef struct node{
char a[10];
char b[10];
char c[10];
int f;
struct node* next;
}node;
int main()
{
node* temp;
int d= sizeof(node *);
printf("Size of structure pointer = %d",d);
temp= (node*)malloc(sizeof(node*));
int c = sizeof(temp);
printf("Size of Temp = %d\n",c);
}
```````````````````
/*
Here both Temp and node* is having a size of 8 bytes.
But the size of the structure 'node' is 38 bytes(total size of the members).
So how can the pointer Temp allocate that much memory if its size is just 8 bytes ?
*/
Because you don't store data in pointers. Pointers point at data allocated elsewhere, hence the name "pointer". sizeof(node*) is wrong and the size of the pointer itself is irrelevant.
You should do
temp = malloc(sizeof *temp); // equivalent of sizeof(Node)
...
free(temp);
This is the pointer to the node struct, you don't need to allocate space for it. It can point to the node structure.
struct node *node_ptr;
If you want to store node structure at some pointer, you need to allocate space for the node structure NOT THE POINTER
node *node_data = malloc(sizeof(struct node));
You don't need to cast the result from the malloc, it is bad { see casting for malloc }
Pointer is just the pointer. It you are a tourist guide in the war museum and use the pointer to show the tank - what is the weight of the pointer in your hand? The weight of the wooden stick or the weight of the tank?
First lets understand about malloc:
Malloc is a function which allocates memory in a HEAP part of RAM. If we define a variable, usually it gets allocated in STACK part of RAM.
temp = (int*)malloc(n*sizeof(int));
this code allocates a memory in HEAP.
Now lets understand about ponters:
consider the following code.
int a;
int *p;
p=&a;
in the about line of code the pointer 'p' is storing the address of the variable 'a'.
Depending on the word length of your system(32bit or 64bit), the size of the pointer variable 'p' changes. It can be 2bytes or 4bytes or 8bytes. 8bytes is because in 64bit machine, "long int" can takes 8bytes.
Now lets understand about both pointers with structure:
struct value{
int a;
int b;
char c;
};
Since above code is a definition of structure, memory won't get allocated.
struct value s;
now the memory gets allocated in Stack.
struct value *s;
s = (struct value*)malloc(sizeof(struct value));
here the memory gets allocated in Heap.
Even though 's' is structure pointer it still stores the address of the whole structure 'value', it's size will be 4/8. It points to whole structure not the particular member of structure.
The general structure 's' will have the data part of all its members. So the size will be 5 or 9 depending of the machine and the padding.
struct s{
int a; /* 4 bytes */
char b; /* 1 byte */
/* 1 padding byte */
short c; /* 2 bytes */
};
Refer Data Structure Padding
This question already has answers here:
Structure padding and packing
(11 answers)
Closed 3 years ago.
I got confused with the size allocation with my gcc compiler, can any one help me how the size get allocated for the following code.
struct node
{
int data;
struct node *next;
};
sizeof(struct node) it gives an output as 16.
struct node
{
int data;
};
sizeof(struct node) it gives an output as 4.
struct node
{
struct node *next;
};
sizeof(struct node) it gives an output as 8.
struct node
{
int data;
struct node *next;
}*link;
sizeof(link) is always 8, even if i add few more elements to structure.
On your specific platform, it looks like an int has size 4 and a pointer has size 8. It also looks like it wants to align pointers on an 8-byte boundary.
So if struct node just contains an int, then the its size is 4. If it just contains a pointer, its size is 8. If it contains both an int and a pointer, then it needs 12 bytes, but in order to maintain the alignment of the pointer, it pads the structure to a multiple of 8, resulting in a size of 16.
In your final example, you have link defined as a pointer to a struct node. In this case, it doesn't matter what a struct node contains. Since link is just a pointer, its size will always be 8.
Again, note that this is just a best guess for your platform. None of this is guaranteed, and it can vary from one platform to another.
sizeof return size in bytes
int have 32 bits = 4 bytes
Any pointer char*, struct any* has const sizeof depends memory structure, in your case is 8.
Because of memory alligment your first example has sizeof = 16, more here: https://en.wikipedia.org/wiki/Data_structure_alignment , you can add #pragma pack(1) and see diffrents, should be 4 + 8 = 12
sizeof(link) will always return 8 bytes because that's the size of a pointer in a 64 bits computer.
If you want the size of the structure you need to do sizeof(struct node) as it will give you the size of the actual struct.
And for a linked list type struct I would recomend you something like this
typedef struct node Node, *pnode;
struct node{
//some vars
pnode next;
}
Then you'll just need to declare it your main or anywhere you as
pnode list = NULL;
sizeof(Node) //for memory allocation
I am trying to assign the address of one of a structure, which is named as node, to another one named tmp, which has the same type--Node. However, the address of tmp is always less 8 then the address of node. Why is that? thanks!
#include <stdio.h>
#include <stdlib.h>
typedef struct _node
{
int data;
struct _node *next;
}Node;
int main()
{
Node *node = (Node*)malloc(sizeof(Node));
Node *tmp;
tmp = node;
printf("%d\n",&node);
printf("%d\n",&tmp);
}
I am guessing that you expected the output to be the same for both lines.
For that to happen, you have to print the values of the pointers, not the addresses of the pointers.
After
tmp = node;
the value of tmp is the same as the value of node but the addresses of the two variables are always going to be different.
I suspect you meant to use:
printf("%p\n", node); // Use %p for pointers, not %d
printf("%p\n", tmp);
Likely pointers are 8 bytes on your platform. So since you allocated one right after the other, they are 8 bytes apart.
You are confused about the difference between the value of a variable (of pointer type) and its address. You can change the value of a variable, as you do in your code by means of the assignment operator:
tmp = node;
but a variable's address is the most essential of its defining characteristics. You cannot change that.
You are printing the addresses of your pointers (sort of -- the field descriptors in your format string are wrong). To print their values, you want this:
printf("%p\n", (void *) node);
printf("%p\n", (void *) tmp);
The key distinction is of course that the above does not employ the address-of operator (&). Additionally, the %p field descriptor is what you need to print a pointer value, but it is specifically for void * values. And that's the reason for the casts.
I am working on a project that implements the buddy allocation algorithm in C. Using mmap(), I allocated a space of 1GB of continuous memory. It looks like this:
char * base = mmap(NULL, MAX_MEM, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, 0, 0);
I have a struct that I am trying to place into that space. The struct looks like this:
typedef struct Node {
unsigned char header;
struct Node *next;
struct Node *prev;
}node;
I am unsure how to get a node to go into that spot. I tried the code below because I didn't want to put the node at the very beginning, but when I print out the pointer they show much different spots
void *ptr = (struct Node *) base + 512;
printf("base: %p\n", base);
printf("ptr: %p\n", ptr);
My terminal window prints out this:
base: 0x102ef1000
ptr: 0x102ef4000
But this doesn't seem right because the pointers are 12288 spaces away from each other in memory instead of just 512. What am I doing wrong?
void *ptr = (struct Node *) base + 512;
means ((struct Node *) base) + 512.
What you want is
void *ptr = (struct Node *) (base + 512);
So you skip 512 bytes from the beginning of allocation.
According to the post, cast has higher precedence than addition.
Remember, as you cast base to a struct Node * adding to it will now add the size of a struct Node to the pointer, therefore you are adding sizeof(struct Node) * 512 to it. this is probably not what you want. Given it is a 24 byte struct this makes it 24 * 512 = 12288.
The reason it is 12 bytes is that is contains 2 8 byte pointers, a 1 byte char and 7 bytes of padding to ensure the pointers are aligned to 8 bytes.
To solve this simply omit the cast, it will leave base as a char * and increment it 512 bytes as wanted.
void *ptr = base + 512;