1

I was writing a code the other day,to do some vector math. That used dynamically allocated structure members. The code that initialized instances of of such structures had to somehow know whether or not the instances was already initialized or not.
I used the following method...
The file vector.h includes among other things...
File: "vector.h"

#include<stdint.h>
#include"complex.h" // struct cplx defined here

#define SET 0x00
#define UNSET 0x01

struct vector {
    struct cplx *res; // for resolution vectors
    uint8_t status;
    uint8_t dim; // dimension of vector
};

typedef struct vector Vector;

void setvector(Vector *vec,int _dim,...);
//ellipsis contains pairs of double values representing the complex magnitude of each resolution vector in order.

And file "setvector.c" ...

#include<stdarg.h>
#include"vector.h"
#include<limits.h>
#include<stdlib.h>

void setvector (Vector *vec,int _dim,...)
{
   if(vec->status != SET){
       vec->res = calloc(vec->dim = (uint8_t)_dim, sizeof(*vec->res));
       vec->status = SET;
    }

va_list dptr;
va_start (dptr, _dim);
/*blah..blah..blah........
.....some code......*/
    //To modify already set vectors
    vec->res = realloc(vec->res,(vec->dim = (uint8_t)_dim) * sizeof(*vec->res));
/*..blah...*/
va_end(dptr);
}

Suppose a instance of a vector object is initialized locally (run-time) in some function (e.g main), then their is a small chance that the structure member status which is supposed to contain "garbage value" on initialization, has the same value as the macro SET. To be presize, for type uint8_t assuming all values have equal probability, the chance of this "garbage value" to be equal to SET is exactly one in 256 i.e 1/256. This would mean that the routine setvector would fail - by calling realloc without calling calloc - at least once every 256 calls to it. (This would lead to a program that failed randomly with segmentation fault error, for no apparent reason). This chance can be reduced by setting status to 4 byte int to once every 2^32 calls, But that will be just evading the problem, not solving it.

Is there any way to create routines in C that will initialize a structure instance without this problem. for example, by setting default values to structure members ?

Thx in advance :-).


I know this issue can be resolved by resorting to C++ structures, and their constructors functions, .(I think c++ structures support default values, but I'm not sure).
But I'm trying to do it in C.

  • 1
    How are you dynamically allocating your vector(s)? If using `malloc`, then consider `calloc`, instead ... that sets all allocated memory to zero, so you know your initial value of `status` will be `0`. – Adrian Mole Aug 09 '21 at 08:45
  • Initialize res to NULL. – stark Aug 09 '21 at 11:16
  • I should have been more clear about this in the Question (My bad). I was trying to make the function, ```setvector``` be prepared for negligence of the user in initialising a ```Vector```. Basically I was trying to achieve a c++ like feature in c, by trying to "hide" the actual working of the structure. – Siddharth Bhat Aug 10 '21 at 05:21
  • @Adrian Mole, Thanks for bringing that into my knowledge. I was *not* aware of that behaviour, of ```calloc```. – Siddharth Bhat Aug 10 '21 at 05:32

1 Answers1

1

Is there any way to create routines in C that will initialize a structure instance without this problem. for example, by setting default values to structure members ?

Yes, you can use designated initializers on most modern (C99+) compilers.

Hence, from within a function, you could do this:

    Vector v = {.status = UNSET};
    setvector(&v, n);

More info on designated initializers here

th33lf
  • 2,177
  • 11
  • 15