struct array initialization in C - c

Here is part of my code. I would like to initialize only the arraylist[0] as arraylist[0].x = 0 and arraylist[0].y = 0. I do not need to initialize the rest of the struct array. How can I do it? Thank you.
#include <stdio.h>
struct example {
int x;
int y;
};
struct example arraylist[40];
int main(int argc, char *argv[]){
printf("%d\n %d\n", arraylist[0].x, arraylist[0].y);
return 0;
}

You can initialise any particular element of the struct array.
For example:
struct example arraylist[40] = { [0]={0,0}}; //sets 0th element of struct
struct example arraylist[40] = { [5]={0,0}}; //sets 6th element of struct
This is called Designated Initializers which used to be a GNU extension before C99 adapted it and is also supported in standard C since C99.

Since you are talking about a variable in file scope, here, you don't have to do anything, since such variables are always initialized by 0 if you don't provide an explicit initializer.

In C, once you initialize part of a struct / array, you initialize the rest of it with 0.
You should have no problem with that, as you should not access uninitialized variables in first place, and their value is not defined.

In C all static and extern variables are initialized to 0 unless explicitly initialized otherwise.

Related

How to init struct pointer variables with NULL?

I have such two struct
struct table_element
{
struct table_val * table_val_arr;
int count_arr;
};
struct hash_table
{
struct table_element table_element_arr[MAX_NUMBER];
};
and here my test method
void test(struct hash_table * table)
{
int count;
struct table_element * tab_element;
for(count = 0; count < MAX_NUMBER; count++)
{
tab_element = &table->table_element_arr[count];
if(tab_element->table_val_arr == NULL)
{
printf("\nNULLLL!!!!!\n");
}
else
{
printf("\nOK!!!!!\n");
}
}
}
and here how I use it
int main(int argc, char **argv)
{
struct hash_table m_hash_table;
test(&m_hash_table);
...
I expect that all value would be NULL, but sometimes I get OK sometimes NULL...
What am I doing wrong?
How to init it with NULL?
Non-static variables defined inside of a function have indeterminate values if not explicitly initialized, meaning you can't rely on anything they may contain.
You can fix this by giving an initializer for the variable:
struct hash_table m_hash_table = {{NULL, 0},{NULL, 0},/*repeat MAX_NUMBER times*/};
Or by using memset:
memset(&m_hash_table, 0, sizeof(m_hash_table));
If you don't explicitly initialise a variable in C, it'll have an undefined value. eg.
int fish; // could be zero, -100, 3805, ...anything
int chips = 5; // will definitely be 5.
The same is true of pointers. They could point anywhere. And finally, the same is true of a structure's members.
There are two common approaches to this 'problem' depending on your needs.
memset the whole thing to zero:
struct hash_table m_hash_table;
memset( &m_hash_table, 0, sizeof(m_hash_table) );
Result: all the variables will be zero, all the pointers will be NULL1.
Explicitly set everything by hand:
struct hash_table m_hash_table;
for (int i = 0; i < MAX_NUMBER; i++)
{
m_hash_table.table_element_arr[i].table_val_arr = NULL;
m_hash_table.table_element_arr[i].count_arr = 0;
}
A third option is to provide initialisation when you declare the struct, but it's logically equivalent to option 2.
struct hash_table m_hash_table = { { NULL, 0 }, { NULL, 0 }, ... /*etc*/ };
1 As per the comments, it is true that there exist some architectures where a bit pattern of all zeros is not equivalent to NULL, and hence the memset( ..., 0, ...) approach is not strictly valid. However, for all practical purposes, on any modern platform, it's a perfectly valid, idiomatic solution.
(IMHO anyone using an architecture where this isn't true isn't going to be looking for advice on SO about how to initialise their structures!)
You declared m_hash_table as an automatic variable. Such variables are usually located on the stack. The stack space may be filled with random content.
You have three options.
Declare it as a static variable: static struct hash_table m_hash_table;
Use memset(): memset(&m_hash_table, 0, sizeof(m_hash_table));
Use explicit initializer: struct hash_table m_hash_table = {};
UPDATE#1
According to this http://c-faq.com/null/machexamp.html information options #1 and #2 do not work correctly on some hardware. The option #3 gives the desired result.
UPDATE#2
The discussion below reveals a new truth. Option #1 is the best.
The struct hash_table m_hash_table; is automatic storage, (vs say, static, in which case it would be automatically initialised.) This means the contents of the variable are indeterminate. One could initialise it several ways, see initialisation, (or the other answers.) However, I think that this is important to know that memset is not a proper way to initialise a null pointer, (the C FAQ has an entire section on null pointers.) Like Pascal's nil or Java's null, 0 in pointer context has a special meaning in C, the null pointer. It commonly is all-bits-zero, leading to the mistaken impression that 0 is actually all-bits-zero, but this is not always the case. The general idiomatic way is to have a constructor in which you set any null pointers with explicit,
te->table_val_arr = 0; /* or NULL. */
te->count_arr = 0;
Edit: three initialisations are shown:
#include <stddef.h>
#include <assert.h>
/* `struct table_val` is undefined in this limited context. */
struct table_element {
int * table_val_arr;
int count_arr;
};
/** `te` is a value that gets initialised to be empty. */
static void table_element(struct table_element *const te) {
assert(te);
te->table_val_arr = 0; /* Or `NULL`, depending on your style. */
te->count_arr = 0;
}
struct hash_table {
struct table_element table_element_arr[100];
};
static size_t hash_table_size =
sizeof ((struct hash_table *)0)->table_element_arr
/ sizeof *((struct hash_table *)0)->table_element_arr;
/** `ht` is a value that gets initialised to be empty. */
static void hash_table(struct hash_table *const ht) {
size_t i;
assert(ht);
for(i = 0; i < hash_table_size; i++)
table_element(ht->table_element_arr + i);
}
/* This is automatically initialised to all-elements-zero, (which is not
necessary all-bits-zero.) */
static struct hash_table g_hash_table;
int main(void) {
struct hash_table m_hash_table = {{{0,0}}}; /* Initialiser. */
struct hash_table table; /* Garbage. */
hash_table(&table); /* Now fixed. */
return 0;
}
The dynamic way of using constructor functions is scalable to large objects and objects that one doesn't want to necessarily initialise with zero; C++ expands this greatly to RAII. The initialisation in the declaration is limited to constant expressions, and thus is probably the most efficient. The static option changes the storage class of the object and is probably unsuitable except for objects that one wanted to declare static anyway.
A colleague (not on SO) has suggested this answer: Partially initializing a C struct
Which says (in essence) if you initialise the first element of your structure, the compiler will automatically initialise everything else to zero or NULL (as appropriate) for you.
Copying from that...
10 If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate. If an object that has static storage duration is not initialized explicitly, then:
—if it has pointer type, it is initialized to a null pointer;
—if it has arithmetic type, it is initialized to (positive or unsigned) zero;
—if it is an aggregate, every member is initialized (recursively) according to these rules;
—if it is a union, the first named member is initialized (recursively) according to these rules.
...
21 If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration.

Why is the output of this C program 0?

In this code I am trying to pass a pointer to the structure and then use this pointer to work on the structure members, but why is the output always showing 0?
#include<stdio.h>
#include<string.h>
struct student
{
int go;
} s;
void m();
void main()
{
m(&s);
printf("%d",s.go);
}
void m(struct student *ptr)
{
ptr->go;
}
struct student
{
int go;
}s;
creates a global variable. Global variables are zero initialized unless they are initialized explicitly. That statement is equivalent to:
struct student
{
int go;
};
struct student s = {0};
Hence the value of s.go is 0. The call to m does not change the values of any variables. It has no effect on the output. The output will be 0 even if the call to m(&s) is removed.
The global variable s is initialized with all members 0.
Nothing changes the value of s.go, so the output is 0.
Your question has all sorts of errors, here they are, in no particular order:
you don't need #include <string.h> if you aren't using any "string" functions
you shouldn't use global variables (if you did, it would eliminate the need to pass the pointer to s to functions to access the struct); you should remove the global variable (i.e., make it local) and continue to pass the pointer-to-struct as you are to m() in order to be able to access it outside of main() (where you should declare it)
your signature for main() is incorrect as I pointed out in a comment to OP, and naturally you are missing the return 0; statement in main() because of this
you are missing a newline in your printf()
you aren't actually doing anything with ptr->go in m(); you aren't assigning anything to it or otherwise using it. It is printing zero because, as others have pointed out, global variables (because they are static,) are (default-)initialized
Here is an example with corrections (note you can initialize s as described by others if you wish to use it's value before you modify/set it):
#include <stdio.h>
struct student
{
int go;
};
void m();
int main(void)
{
struct student s;
m(&s);
printf("%d\n", s.go);
return 0;
}
void m(struct student *ptr)
{
ptr->go = 5;
}
When you declare your structure as global , their members are always initialize with its default value, if int than '0' and if char or string than '\0' . So you are getting Value 0.
struct student
{
int go;
} s;

defining structure variable during declaration

I have been trying something in structures in C.
struct val{
unsigned int a : 1 ;
}store[100] ;
Now I want to initialize all the array members value to 1. That is, I want all the array members to have their variable a assigned to 1. I can use a loop for that but how can I do this during the declaration?
struct val
{
unsigned int a=1 : 1 ;
}store[100];
How can i achieve this? The above syntax is coming out to be wrong in code::blocks.
struct val
{
unsigned int a : 1;
}store[100];
I initially thought that what you were doing was a bitfield initialization. Further research though suggested I am wrong, and that you are trying to use gcc's designated initializers. What you want to do, is not possible that way. I found another way in your code that you can do it, though:
typedef struct {
unsigned int a;
} val;
then, where you want to initialize the array, you will do something like that:
val values[100] = {[0].a = 1};
This works by exploiting this behavior of gcc:
If the same field is initialized multiple times, it has the value from the last initialization. If any such overridden initialization has side-effect, it is unspecified whether the side-effect happens or not. Currently, GCC discards them and issues a warning.
My Test Program follows:
#include <stdio.h>
struct val {
unsigned int a;
};
int
main (void)
{
struct val value[100] = {[0].a = 1};
printf ("A random val's value is %d\n", value[40].a);
return 0;
}
Compiles and works cleanly on my GCC 4.9.1.
It's not possible.
You can use a loop, or, if by any chance you want to initialize all struct's data members to a specific value, you can also use memset:
struct val {
unsigned int a : 1 ;
} store[N];
memset(store, value, N * sizeof(struct val));
Before declaring a struct variable you can't initialize its member. Initialization can be done as
struct val{
unsigned int a : 1;
}store[100] = {[0].a = 1} ; // Designated initializer
but it will initialize a member of other elements of store to 0. To initialize member a of all elements of store you need a loop.

About default C struct values, what about this code?

I'm trying to create structs with default values. I don't know how to accomplish this because every code that I see, is about initialising, and I would it for the natural way like...
struct stuff {
int stuff_a = 1;
int stuff_b = 2...
...and so on...
};
and looking about, I found this (C++) code:
struct a{ a() : i(0), j(0) {}; INT i; INT j;}
I never saw anything like this for C. Please, help me to understand it; I think that it is very nice!
UPDATE: Wait, I'm asking about C!!!! Why changed my question? If that is not possible in C just say... I don't know C++, I didn't know that was about C++...
If you want to set a struct object in one go and you have a C99 compiler, try this:
struct stuff {
int stuff_a;
int stuff_b;
// and so on...
};
struct stuff foo;
/* ... code ... */
foo = (struct stuff){.stuff_b = 42, .stuff_a = -1000};
Otherwise, with a C89 compiler, you have to set each member one by one:
foo.stuff_b = 42;
foo.stuff_a = -1000;
Running example # ideone : http://ideone.com/1QqCB
The original line
struct a{ a() : i(0), j(0) {} INT i; INT j;}
is a syntax error in C.
As you have probably learned from the other answers, in C you can't declare a structure and initialize it's members at the same time. These are different tasks and must be done separately.
There are a few options for initializing member variables of a struct. I'll show a couple of ways below. Right now, let's assume the following struct is defined in the beginning of the file:
struct stuff {
int stuff_a;
int stuff_b;
};
Then on your main() code, imagine that you want to declare a new variable of this type:
struct stuff custom_var;
This is the moment where you must initialize the structure. Seriously, I mean you really really must! Even if you don't want to assign specific values to them, you must at least initialize them to zero. This is mandatory because the OS doesn't guarantee that it will give you a clean memory space to run your application on. Therefore, always initialize your variables to some value (usually 0), including the other default types, such as char, int, float, double, etc...
One way to initialize our struct to zero is through memset():
memset(&custom_var, 0, sizeof(struct stuff));
Another is accessing each member individually:
custom_var.stuff_a = 0;
custom_var.stuff_b = 0;
A third option, which might confuse beginners is when they see the initialization of struct members being done at the moment of the declaration:
struct stuff custom_var = { 1, 2 };
The code above is equivalent to:
struct stuff custom_var;
custom_var.stuff_a = 1;
custom_var.stuff_b = 2;
... create structs with default values ...
That is impossible in C. A type cannot have default values. Objects of any type cannot have a default value other than 0, though they can be initialized to whatever is wanted.
The definition of a struct is a definition of a type, not of an object.
What you asking is about the same thing as a way to have ints default to, say, 42.
/* WRONG CODE -- THIS DOES NOT WORK */
typedef int int42 = 42;
int42 a;
printf("%d\n", a); /* print 42 */
Or, adapting to your example
/* WRONG CODE -- THIS DOES NOT WORK */
struct stuff {
int42 stuff_a;
int65536 stuff_b;
}
struct stuff a;
printf("%d\n", a.stuff_b); /* print 65536 */
Update: This answer assumes we 're talking about C++ because the code posted in the answer is not legal C.
struct a {
a() : i(0), j(0) {} // constructor with initialization list
int i;
int j;
}
The line marked with the comment is simply the constructor for instances of struct a (reminder: structs are just like classes, except that the default member visibility is public instead of private).
The part after the : is called an initialization list: it allows you to initialize the members of the struct with values (either constants or passed as constructor parameters). Initialization of members in this list happens before the body of the constructor is entered. It is preferable to initialize members of classes and structs this way, if at all possible.
See also C++: Constructor versus initializer list in struct/class.
in C (pre C99) the following also works:
#include <stdio.h>
typedef struct
{
int a;
int b;
int c;
} HELLO;
int main()
{
HELLO a = {1,2,3};
printf("here: %d %d %d\n",a.a,a.b,a.c);
exit(1);
}
See codepad
I'm not sure quite sure what your problem is. The standard way of initialising structures in c is like this:
struct a_struct my_struct = {1, 2};
Or the more recent and safer:
struct a_struct my_struct = {.i1 = 1, .i2 = 2};
If there is more than one instance of a structure, or it needs to be re-initialised, it is useful to define a constant structure with default values then assign that.
typedef struct a_struct {
int i1;
int i2;
} sa;
static const sa default_sa = {.i1 = 1, .i2 = 2};
static sa sa1 = default_sa;
static sa sa2 = default_sa;
// obviously you can do it dynamically as well
void use_temp_sa(void)
{
sa temp_sa = default_sa;
temp_sa.i2 = 3;
do_something_with(&temp_sa);
}
// And re-initialise
void reset_sa(sa *my_sa)
{
*my_sa = default_sa;
}
Type initializer is not possible in C.
A value must be stored in the memory.
A type does not occupy memory, what occupies memory is a variable of that type.
struct stuff; is a type; it does not occupy memory
struct stuff aStuff; is a variable of that type; aStuff occupies memory
Because a type does not occupy memory, it is not possible to save values into a type.
If there is syntactic sugar to support store/initialize values into a type then there must be additional code that is inserted to assign values to every instant variables of that type (e.g: in constructor in C++). This will result in a less efficient C if this feature is available.
How often do you need to retain this default values? I think it is unlikely. You can create a function to initialize variable with the default values or just initialize every fields with the values you want. So type initializer is not fundamental thing. C is about simplicity.
Can't initialize values within a structure definition.
I'd suggest:
typedef struct {
int stuff_a;
int stuff_b;
} stuff ;
int stuffInit(int a, int b, stuff *this){
this->stuff_a = a;
this->stuff_b = b;
return 0; /*or an error code, or sometimes '*this', per taste.*/
}
int main(void){
stuff myStuff;
stuffInit(1, 2, &myStuff);
/* dynamic is more commonly seen */
stuff *dynamicStuff;
dynamicStuff = malloc(sizeof(stuff)); /* 'new' stuff */
stuffInit(0, 0, dynamicStuff);
free(dynamicStuff); /* 'delete' stuff */
return 0;
}
Before the days of Object Oriented Programming (C++), we were taught "Abstract Data Types".
The discipline said 'never access your data structures directly, always create a function for it' But this was only enforced by the programmer, instructor, or senior developer, not the language.
Eventually, the structure definition(s) and corresponding functions end up in their own file & header, linked in later, further encapsulating the design.
But those days are gone and replaced with 'Class' and 'Constructor' OOP terminology.
"It's all the same, only the names have changed" - Bon Jovi.

Why can't we initialize members inside a structure?

Why can't we initialize members inside a structure ?
example:
struct s {
int i = 10;
};
If you want to initialize non-static members in struct declaration:
In C++ (not C), structs are almost synonymous to classes and can have members initialized in the constructor.
struct s {
int i;
s(): i(10)
{
}
};
If you want to initialize an instance:
In C or C++:
struct s {
int i;
};
...
struct s s_instance = { 10 };
C99 also has a feature called designated initializers:
struct s {
int i;
};
...
struct s s_instance = {
.i = 10,
};
There is also a GNU C extension which is very similar to C99 designated initializers, but it's better to use something more portable:
struct s s_instance = {
i: 10,
};
The direct answer is because the structure definition declares a type and not a variable that can be initialized. Your example is:
struct s { int i=10; };
This does not declare any variable - it defines a type. To declare a variable, you would add a name between the } and the ;, and then you would initialize it afterwards:
struct s { int i; } t = { 10 };
As Checkers noted, in C99, you can also use designated initializers (which is a wonderful improvement -- one day, C will catch up with the other features that Fortran 66 had for data initialization, primarily repeating initializers a specifiable number of times). With this simple structure, there is no benefit. If you have a structure with, say, 20 members and only needed to initialize one of them (say because you have a flag that indicates that the rest of the structure is, or is not, initialized), it is more useful:
struct s { int i; } t = { .i = 10 };
This notation can also be used to initialize unions, to choose which element of the union is initialized.
Note that in C++ 11, the following declaration is now allowed:
struct s {
int i = 10;
};
This is an old question, but it ranks high in Google and might as well be clarified.
Edit2: This answer was written in 2008 and relates to C++98. The rules for member initialization have changed in subsequent versions of the language.
Edit: The question was originally tagged c++ but the poster said it's regarding c so I re-tagged the question, I'm leaving the answer though...
In C++ a struct is just a class which defaults for public rather than private for members and inheritance.
C++ only allows static const integral members to be initialized inline, other members must be initialized in the constructor, or if the struct is a POD in an initialization list (when declaring the variable).
struct bad {
static int answer = 42; // Error! not const
const char* question = "what is life?"; // Error! not const or integral
};
struct good {
static const int answer = 42; // OK
const char* question;
good()
: question("what is life?") // initialization list
{ }
};
struct pod { // plain old data
int answer;
const char* question;
};
pod p = { 42, "what is life?" };
We can't initialize because when we declared any structure than actually what we do, just inform compiler about their presence i.e no memory allocated for that and if we initialize member with no memory for that. Normally what happens when we initialize any variable that depends on the place where we declared variable compiler allocate memory for that variable.
int a = 10;
if it's auto than in stack memory going to allocate
if it's global than in data sections memory going to allocate
So what memory is required to hold that data but in case of structure no memory is there so not possible to initialize it.
As you said it's just a member not a variable. When you declare a variable the compiler will also provide memory space for those variables where you can put values. In the case a of a struct member the compiler is not giving memory space for it, so you cannot assign values to struct members unless you create a variable of that struct type.

Resources