Thread: automatic initialization of a structure to zero (smthg like a default constructor)

  1. #1
    Registered User
    Join Date
    Oct 2005
    Posts
    1

    automatic initialization of a structure to zero (smthg like a default constructor)

    Hi,

    when I define a structure, specialy those with pointers inside, I create a init function to set all members to zero or NULL. Then functions to allocate and deallocate memory for my structure can work well. In order to avoid confusion here is an example with matrices:

    in matrix.h:
    Code:
    typedef struct{
       int row,col;
       double **mat;
    }Matrix;
    and in matrix.c:
    Code:
    void initMatrix(Matrix *m){
       m->row = m->col = 0;
       m->mat = NULL;
    }
    
    void freeMatrix(Matrix *m){
       int i=0;
       for( i=0; i<m->row; i++ )
          free(m->mat[i])
       free(m->mat);
       initMatrix(m); //reset the state of the matrix
    }
    
    void allocMatrix(Matrix *m, int row, int col){
       int i=0;
       freeMatrix(m); //protect against double allocation
       m->row = row;
       m->col = col;
       m->mat = (double **) malloc(sizeof(double *)*row);
       for( i=0; i<row; i++ )
          m->mat[i] = (double *) malloc(sizeof(double)*col);
    }
    and in the main source:
    Code:
    void foo(){
       Matrix A;
       init(&A);
       allocMatrix(&A,100,100);
       ...
       freeMatrix(&A);
    }
    my question here is: is there a way to avoid this fastidious initialization procedure and write code like the following?
    Code:
    typedef struct{
       int row=0,col=0;
       double **mat=NULL;
    }Matrix;
    
    void foo(){
       Matrix A;
       allocMatrix(&A,,100,100);
       ...
       freeMatrix(&A);
    }
    The reason is that it is annoying to initialize when there are many matrices. Moreover it would prevent errors if the developer forgets to call the initFunction.

    best regards to those who read till there
    Brice

  2. #2
    Registered Luser cwr's Avatar
    Join Date
    Jul 2005
    Location
    Sydney, Australia
    Posts
    869
    If it's dynamically allocated with malloc, no.

    If it's a single instance or an array, if you initialise the first field/element to 0, it will make the rest 0. ie. struct foo bar = { 0 };

  3. #3
    Registered User
    Join Date
    Sep 2005
    Location
    Sydney
    Posts
    60
    Quote Originally Posted by cwr
    If it's dynamically allocated with malloc, no.
    If calloc were used instead, though, won't that set the memory to zero?

  4. #4
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Yes, but there's no guarintee that all bits 0 is the same as NULL, so this doesn't work for pointers. It will likely work, but it might not, if your implementation has NULL as something other than all zero bits. (There is such an architecture, its name escapes me. Search the forums or your favourite search engine if you're curious.)


    Quzah.
    Hope is the first step on the road to disappointment.

  5. #5
    Registered Luser cwr's Avatar
    Join Date
    Jul 2005
    Location
    Sydney, Australia
    Posts
    869
    Indeed, that was specifically why I didn't suggest a calloc/memset solution.

    The examples of admittedly ancient architectures that have a non-zero NULL are listed in the comp.lang.c FAQ:

    http://www.eskimo.com/~scs/C-faq/q5.17.html

  6. #6
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    Quote Originally Posted by SingaBrice
    The reason is that it is annoying to initialize when there are many matrices. Moreover it would prevent errors if the developer forgets to call the initFunction.
    Then dump the initFunction completely, and just use the alloc:
    Code:
    Matrix *allocMatrix(int row, int col)
    {
      Matrix  *m;
    
      m = malloc(sizeof(*m)); /* Error check! */
    
      int i = 0;
      m->row = row;
      m->col = col;
      m->mat = (double **) malloc(sizeof(double *) * row);
      for (i = 0; i < row; i++)
      {
    	m->mat[i] = (double *) malloc(sizeof(double) * col);
      }
    
      return(m);
    }
    
    void foo(void)
    {
      Matrix  *A;
      A = allocMatrix(100, 100);
      ... 
      freeMatrix(A);
    }
    Also, if you want a safer way to initialise a newly malloc'd structure to have all zeros, use a static struct as a base, and copy it in. This way, if you add additional elements to the structure, you never need worry about their initialisation. Here's an example:
    Code:
    #include <stdio.h>
    
    typedef struct
    {
      int row;
      int col;
      double **mat;
    } Foo;
    
    void initFoo(Foo *f)
    {
      const static Foo myFoo;
      *f = myFoo;
    }
    
    int main(void)
    {
      Foo mainsFoo;
      
      printf ("mainsFoo, uninitialised: %d, %d, %p\n", 
    		  mainsFoo.row,
    		  mainsFoo.col,
    		  mainsFoo.mat);
    
      initFoo(&mainsFoo);
      
      printf ("mainsFoo, initialised: %d, %d, %p\n", 
    		  mainsFoo.row,
    		  mainsFoo.col,
    		  mainsFoo.mat);
    			
      return(0);
    }
    
    /*
    
    mainsFoo, uninitialised: 256, 1, 0040A054
    mainsFoo, initialised: 0, 0, 00000000
      
    */
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  7. #7
    Captain - Lover of the C
    Join Date
    May 2005
    Posts
    341
    Would a call to memset work? If it does, that would make things easier:

    Code:
    memset(&m,0,sizeof(m));
    It works for other things, but I'm not sure whether it would be correct in this application.
    Don't quote me on that... ...seriously

  8. #8
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    It would have the same possible downside that calloc has. Where pointers whose NULL is not all bits zero wouldn't be initialized correctly.


    Quzah.
    Hope is the first step on the road to disappointment.

  9. #9
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    Why would calling an additional function make it easier?
    ... and no, it wouldn't work anyway (see the comments above about NULL pointer initialisation)


    [goddamit, beat!]
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  10. #10
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    Using cwr's example, I'm assuming from the length of this thread that if you do:
    Code:
    struct foo bar = { 0 };
    That this doesn't necessarily set the pointers within the struct to the null pointer. Otherwise this would be the quick solution.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  2. Tab Controls - API
    By -KEN- in forum Windows Programming
    Replies: 7
    Last Post: 06-02-2002, 09:44 AM
  3. Serial Communications in C
    By ExDigit in forum Windows Programming
    Replies: 7
    Last Post: 01-09-2002, 10:52 AM
  4. C structure within structure problem, need help
    By Unregistered in forum C Programming
    Replies: 5
    Last Post: 11-30-2001, 05:48 PM
  5. structure member initialization
    By ivandn in forum C Programming
    Replies: 4
    Last Post: 10-27-2001, 01:27 PM