Search code examples
cfieldbitbit-fields

C - Bit Fields not modified when init


I wonder why after my malloc all modifications aren't working. Here is the code I used to illustrate this :

#include <stdio.h>
#include <stdlib.h>

struct Age {
   unsigned int age : 16;
   unsigned int two : 2;
   unsigned int notToBeInitialed: 2;
};

int init(struct Age * p){
 p = (struct Age *) malloc( sizeof(struct Age) );
 p->age = 5;
 return 0;
}

int change(struct Age * p){
   p->age = 99; 
}

int getValue(struct Age * p){
  return p->age;    
}

int main(void) {
    struct Age test;
    init(&test);
    printf( "Age.age : %d\n", getValue(&test) ); // gives me 0 , expected 5
    change(&test);
    printf( "Age.age : %d\n", getValue(&test) ); // gives me 99 
    return 0;
}

What have I done wrong ?

Thanks for your help.

Source : http://www.tutorialspoint.com/cprogramming/c_bit_fields.htm Ideone : https://ideone.com/O59tqZ


Solution

  • You clearly misunderstand the difference between automatic storage and dynamic memory allocation.

    Local variables

    struct Age test
    

    Defines an Age object using automatic storage. You don't need to do anything else, this object exists and is now usable. The only downside to declaring such objects is that they exists throughout their declaration scope. You should not call init (at least not the malloc part) on this object, since it is already initialized, just set it's value using test.age.

    The following will work as expected:

    int main(void) {
        struct Age test;
        test.age = 5;
        printf( "Age.age : %d\n", getValue(&test) );
        change(&test);
        printf( "Age.age : %d\n", getValue(&test) );
        return 0;
    }
    

    Dynamic memory allocation

    On the other hand, the following:

    p = (struct Age *) malloc( sizeof(struct Age) );
    

    Uses dynamic memory allocation. New memory is allocated and then a pointer is returned to you. In this case you decide to use this memory for holding an Age object.

    int init(struct Age ** p){
        *p = (struct Age *) malloc( sizeof(struct Age) );
        (*p)->age = 5;
    }
    
    int main(void) {
        struct Age * test;
        init(&test)
        printf( "Age.age : %d\n", getValue(test) );
        change(test);
        printf( "Age.age : %d\n", getValue(test) );
        return 0;
    }
    

    Summary

    These two methods are mutualy exclusive. When you are creating a local variable there is not point in allocating additional memory for it.