-1

when printing size allocated by malloc for structure pointer its throw segmentation fault but good for integer pointer?

malloc size is available at one back to its base address and i m dereferencing it to get the size but getting segmentation fault for structure pointer but if it is integer or char pointer then it good please can any one explain?

    #include<stdio.h>
    #include<stdlib.h>
    struct st
   {
         int roll;
         char name[10];
   };

   int main()
  {
       struct st *p,var[3];
       p=malloc(sizeof(struct st)); // here i allocating memory in heap
       printf("%d\n",*(p-1));      // printing allocated memory it good when *p is interger pointer but if structure pointer then it throw segmentation fault why?
  }
trincot
  • 317,000
  • 35
  • 244
  • 286

3 Answers3

1

Warning: Your application is relying on an implementation detail of your particular heap implementation, it's not supported by the C standard and and is likely to break on other systems.

Over to the problem. In your heap implementation, the size of a heap block is stored right before the heap block itself. This helps free to release the right amount of memory. The following image demonstrates this:

     Lower memory ^^^
          ...
     +----------------+
     | size (4 bytes) |
     +----------------+
p -> |  struct st     |
     |     ...        |
     +----------------+

In C, when you perform pointer arithmetic, the pointer is adjusted the same number of bytes as the object it points to. For integer pointers, they are adjusted 4 bytes (assuming you are using 32 integers). As you claim that this work, we can assume that this is the correct number of bytes to adjust the pointer to find the size field.

For the struct pointer, however, the pointer is adjusted sizeof(struct st), on most systems this is 16 bytes (14 for the actual content and another two to pad the struct to ensure correct alignment of the int member, in case the struct is used in arrays). When you do (p-1) you adjust the pointer 16 bytes. Furthermore, when you do *(p-1) you pass the entire structure to printf, something printf does not expect. This is most likely the cause of the crash.

So, what can you do? The best answer to this question is don't, as this is not correct C. The second best answer to this is to write something the explicitly describes that you do, and which could be adjusted to match other systems, for example:

#define OFFSET_TO_HEAP_SIZE 4
#define HEAP_SIZE_TYPE uint32_t

* ( (HEAP_SIZE_TYPE *)(((char const *)p) - OFFSET_TO_HEAP_SIZE) )
Lindydancer
  • 25,428
  • 4
  • 49
  • 68
0

The problem is printf("%d\n",*(p-1));. There are some problems with your code:

1. you are moving an address backwards and then looking for the value of p.

2. you can't print the value of a pointer to a structure as an integer. What you can do is to print the value of the integer which is located in the struct using the p pointer.

3. The roll value in the structure isn't initialized.

First initialize the roll value in the structure and then print it:

printf("%d\n", (*p).roll);

or

printf("%d\n", (p->roll));

If you want to print how much memory is allocated to *p simply write:

printf("%ld", sizeof(struct st));

Igor Pejic
  • 3,658
  • 1
  • 14
  • 32
  • @lgor please try to understand question asked and ya of course i am moving pointer back because size allocated by malloc is available at this position. – carrer carrer Aug 29 '14 at 06:47
  • @carrercarrer not true. You don't need to move backwards. Is your question how to print the memory allocated to *p? – Igor Pejic Aug 29 '14 at 06:48
  • @Jayesh when we allocate a size lets take malloc(0) it will allocated minimum of 17 byte not 0 now if malloc (12) still it will be 17 byte but if malloc(13) then 25 byte the difference is maintain because to store the information of allocated byte and when array is store in heap then if in worst case if contiguous memory is not available then it will go for circular link internal and again this info are need some extra space to store thus difference is maintain and all this are available at one back of base adrress of pointer which is pointing to memory in heap.You can check dennis Ritchie – carrer carrer Aug 29 '14 at 07:03
  • @carrercarrer malloc(0) return 17 bytes??? how? it's not defined.but probably it's return NULL. – Jayesh Bhoi Aug 29 '14 at 07:10
  • @Jayesh NO its depend on data type if its integer then 17byte if char or float then 0 byte .. ex- int *p ; p=malloc(0); printf("%d",*(p-1)); complie it and see – carrer carrer Aug 29 '14 at 07:12
  • @carrercarrer You are just wrong. Who told you that? – Igor Pejic Aug 29 '14 at 07:15
  • @carrercarrer [I think you need to look this](http://stackoverflow.com/questions/2022335/whats-the-point-in-malloc0) – Jayesh Bhoi Aug 29 '14 at 07:17
  • @lgor i strongly recommend first compile it and see it is clear metion in dennis ritchie book and i have complied on two different compiler – carrer carrer Aug 29 '14 at 07:19
  • @Jayesh i have go through it before posting this question and it made me confuse so i read dennis book and got clear picture why don't u compile and figure out its behaviour – carrer carrer Aug 29 '14 at 07:24
  • and for one who vote down please dnot misuse your reputation and simply vote down without understanding th question by think he\she don't know anything coz he has only 7 – carrer carrer Aug 29 '14 at 07:38
0

When you do p=malloc(sizeof(struct st)); P will be allocated (4 + 10 + 2(padding) ) bytes , lets say p is pointing to address 1000

*(p-1) will try to access the value at (1000-16) address which is random and might be not even allocated.

Thats why *(p) would work and *(p-1) doesnot work.

sdn_world
  • 263
  • 2
  • 10