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

• 10-25-2005
SingaBrice
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
• 10-25-2005
cwr
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 };
• 10-25-2005
lemnisca
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?
• 10-25-2005
quzah
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.
• 10-25-2005
cwr
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
• 10-25-2005
Hammer
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   */```
• 10-25-2005
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.
• 10-25-2005
quzah
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.
• 10-25-2005
Hammer
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!]
• 10-26-2005
swoopy
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.