What are values initialized to after calling Struct constructor? - c++

I have a struct defined as:
typedef struct s non_t;
struct s {
char tName;
int rCount;
};
I then initialized it like this:
non_t *s = new non_t();
//s->tName = ???
//s->rCount = ???
So here, what do the values of s->tName and s->rCount get initialized to?? Are they null still? I want to copute something like:
s->rCount = s->rCount + 1
But in order for that to work properly I need s->rCount to be initialized to 0... I guess I'm just confused on how struct initialization really works?

As you add () in new non_t(), members would be value initialized, so member will have value 0 in your case.
With new non_t, the members would be default initialized, so uninitialized in your case.
Adding constructor would avoid those subtleties.
struct s {
s() : tName('\0'), rCount(0) {}
char tName;
int rCount;
};
or in c++11
struct s {
char tName = '\0';
int rCount = 0;
};

int and char cannot be null. The values will be undefined without a constructor that would initialize them.
struct s
{
s() : rCount(0) {}
char tName;
int rCount;
};
This would initialize rCount to zero.

If you need it to be initialized to 0, you should do it in a constructor. :)
Otherwise it'll be set to whatever random piece of memory it's allocated at.
struct s {
s() : tName(' '), rCount(0) {}
char tName;
int rCount;
};

In C++ struct works exactly like a class except all fields are public by default. You can make constructor that will initialize your struct with whatever default values you want.

Related

Constructor Initialization and private variables set inside constructor

My constructor is suppose to only take one variable. But I'm curious if you ca initialize other variables that arent in the constructor defintion.
class WordAnalysis{
private:
int timesDoubled;
word *words;
int wordCount;
int index;
void doubleArrayAndAdd(string);
bool checkIfCommonWord(string);
void sortData();
public:
bool readDataFile(char*); //returns an error if file not opened
int getWordCount();
int getUniqueWordCount();
int getArrayDoubling();
void printCommonWords(int);
void printResult(int);
WordAnalysis(int);
~WordAnalysis();
};
Example: Would any instance of WordAnalysis now have timesdoubled as 0. and would a getter function be able to get this information without a setter?
WordAnalysis::WordAnalysis(int arrSize){
wordCount = arrSize;
int timesDoubled = 0;
int index = 0;
}
Well yes, you can initialize other member variables in the constructor,
even if it doesn't take the corresponding arguments.
However, in the example you gave above:
WordAnalysis::WordAnalysis(int arrSize){
wordCount = arrSize;
int timesDoubled = 0;
int index = 0;
}
You aren't actually initializing the timesDoubled member variables, because you wrote "int" before it, which is declaring a new variable and setting that to 0.
If you want to set the classes timesDoubled variable you have to write:
timesDoubled = 0;
Or if you want to be more explicit about it, you can even write:
WordAnalysis::timesDoubled = 0;
Yes. You can. But, you can do in-class initialization of your data members on declaration. You should use initializer list with constructor to initialize your required data members. All the data members are visible inside the constructor. You can assign their values in it. Technically, using initializer list is initialization and inside the ctor it is assignment when the assignment operator (=) is used.
Here's is the snippet of your code with comments:
class WordAnalysis
{
private:
// Data member initialization on declaration
int timesDoubled { 0 };
word* words { nullptr };
int wordCount { 0 };
int index { 0 };
public:
// Initializing timesDoubled using initializer list
WordAnalysis( const int t ) : timesDoubled{ t }
{
// Assign default values here if need be
index = 10; // assignment
}
// ...
};
Your compiler should be at least C++11 compliant to allow the in-class initializations of data members.
I suggest defining a default constructor such as:
WordAnalysis()
{
timesDoubled = 0;
words[0] = '\0'; //assuming it's an array of char
wordCount = 0;
index = 0;
}
That way all instances of the class would be initialized.

Is there a way in C++ to preinitialize structure or class without a constructors?

I mean: I've a bunch of various structures/classes and all this a splendor shall be initialized with known in advance values. Those structures/classes will never be used other way except the preinitialized one, so there is no any need for constructor -- it's just a waste of extra memory, extra CPU cycles in program, and extra space in source code.
If you have access to a C++11 compiler, you can mark your constructors as constexpr to have them run at compile time. The benefit of this is that way down the road you can still construct your objects at runtime. e.g.
struct Point2D {
constexpr Point2D(int x, int y) : x_{x}, y_{y} {}
int x_, y_;
};
And now you can use Point2D's constructor to initialize it at compile time, instead of runtime:
Point2D p{3, 4}; // no runtime overhead.
Structures and classes can be initialized, in limited circumstances.
struct splendor {
int i, j;
char *name;
};
splendor iforus = { 1, 2, "Extra!" };
Additionally, if you never need the name of the type of the structure:
struct {
int k;
float q;
} anon_e_mouse = { 1, 2.3 };
You can just initialize the members at the point of declaration:
struct Foo
{
int i = 42;
double x = 3.1416;
std::string name = "John Doe";
};
This will set up the default values for all instances:
Foo f;
std::cout << f.i << std::endl; // prints 42
Note that this does not work with C++03, it requires C++11 support.
If a class (or struct) doesn't have a constructor, you can initialize it like so:
MyClass a = MyClass();
or
MyClass * b = new MyClass();
This is called value initialization and it usually amounts to zero-initialization.
C++11 gives you initializer_list.
#include <iostream>
struct s
{
int i;
};
int main() {
s s1={666};
s s2={42};
std::cout<<s1.i<<" "<<s2.i<<std::endl;
return 0;
}
You can also do in-class initialization for member.
#include <iostream>
struct s
{
int i=0;
};
int main() {
s s1; //s1.i = 0
//s s2={42}; //fails
std::cout<<s1.i<<" "<<std::endl;
return 0;
}
But you cant do bot at the same time.
It sounds like you are trying to implement the Singleton Pattern. When you do that, you still need a constructor (in fact, if you want to force it to be a singleton, you have to declare the default constructor as private).
class MySingleton
{
private:
// my data
MySingleton() { /* initialize my data */ }
public:
static MySingleton& GetInstance()
{
static MySingleton instance;
return instance;
}
// other functions
};

Assign int value to a pointer

I need to assign an int value to a pointer, how would I do it?
Below is a small example of what I want.
struct {
int a;
} name;
int temp = 3;
struct name *obj = NULL;
Now, I need to assign this value '3' to struct's 'a'.
With
struct {
int a;
}name;
you already define a struct variable which allocates memory for the struct (e.g. on the stack when it is a local variable inside a function). Then, with int temp = 3;, it is sufficient to assign to the struct member like
name.a = temp;
If you want to declare a struct type only, then use
struct name {
int a;
};
Then you can define any number of struct variables based on this type, like
struct name theName;
and do the same assignment to theName members as above:
theName.a = temp;
Or, you can define a pointer to a struct and then have to allocate the memory yourself:
struct name *namePtr;
namePtr = malloc(sizeof(struct name));
namePtr->a = temp;
Note also that you have tagged your question both with C and C++ - especially with structs, you should decide which language to take - see Differences between struct in C and C++.
Declaring a pointer to a struct doesn't reserve memory for it, so first you have to do that. For example:
obj = malloc(sizeof(*obj));
Now you can assign the value:
obj->a = temp;
Note that the program as it currently stands does not define "struct name", it defines a variable called "name" that holds a struct. This is probably not what you intended.
The basic problem with the code is name is not the name of the structure but an object or a variable of the structure whose name you have already defined.
If u don't want to name the structure, even then still it need memory to be allocated.
struct
{
int a;
}name, *obj;
int temp = 3;
int main()
{
obj=&name; // 'obj' is pointing to memory area of 'name' : Keep this in mind throughout the code
obj->a=temp;
printf("%d %u %d",temp,&temp,obj->a);
return 0;
}
Best option is to put a name to the structure then use its pointer after allocating memory
typedef struct
{
int a;
}name;
int temp = 3;
name *obj = NULL;
int main()
{
obj = (name *)malloc(sizeof(name));
obj->a=temp;
printf("%d %u %d",temp,&temp,obj->a);
return 0;
}
EDIT (thanks Andreas):
Properly, your struct should be declared like so:
struct name {
int a;
};
void foo() {
struct name n; // allocate space for 'struct name' and call it n
struct name *obj; // a pointer to a 'struct name'
int temp = 3;
obj = &n; // make obj point to n
n.a = temp; // direct assignment to a
obj->a = temp; // assignment to a via pointer dereference
// a is now 3 in any case
}
Here is another, annotated, version of your code. Ran this on Eclipse/Microsoft C compiler, this is NOT C++ code.
#include <stdio.h>
main()
{
// define a structure as a data type
typedef struct
{
int *a;
} name;
// allocate storage for an integer and set it to 3
int temp = 3;
// allocate storage for the name structure
name obj;
// set the value of a in name to point to an integer
obj.a = &temp;
// dereference the integer pointer in the name structure
printf("%d\n", *obj.a);
}
obj->a = temp;
just have a try!

enum initialization issue

Here is a sample program :
class BASE
{
public:
enum ABC
{
ZERO,
ONE,
TWO,
LAST
};
BASE(ABC exp): type(exp)
{
A[ZERO] = "1111";
A[ONE] = "22222";
A[LAST] = "LLLL";
}
virtual const char* what()throw()
{
return A[type];
}
private:
const char* A[LAST];
const ABC type;
};
int main()
{
BASE a(BASE::ONE);
cout<<a.what()<<"\n";
return 0;
}
The above program terminates with segmentation fault, as 'type' enum variable is not initialized with specified value but with some random default ?
A is an array of three pointers, A[0], A[1], and A[2].
You have a pointer to "LLLL" which is OK. But when you try to assign that pointer to A[3], there is no such object as A[3].
You declare the array A as
const char* A[LAST];
This means that the indices 0 .. (LAST-1) are all valid. However, in the BASE constructor you perform
A[LAST] = "LLLL";
This is an out-of-bounds access to the array.
If you want a "LAST" entry, try this:
enum ABC
{
ZERO,
ONE,
TWO,
LAST = TWO
};

Are members of a C++ struct initialized to 0 by default?

I have this struct:
struct Snapshot
{
double x;
int y;
};
I want x and y to be 0. Will they be 0 by default or do I have to do:
Snapshot s = {0,0};
What are the other ways to zero out the structure?
They are not null if you don't initialize the struct.
Snapshot s; // receives no initialization
Snapshot s = {}; // value initializes all members
The second will make all members zero, the first leaves them at unspecified values. Note that it is recursive:
struct Parent { Snapshot s; };
Parent p; // receives no initialization
Parent p = {}; // value initializes all members
The second will make p.s.{x,y} zero. You cannot use these aggregate initializer lists if you've got constructors in your struct. If that is the case, you will have to add proper initalization to those constructors
struct Snapshot {
int x;
double y;
Snapshot():x(0),y(0) { }
// other ctors / functions...
};
Will initialize both x and y to 0. Note that you can use x(), y() to initialize them disregarding of their type: That's then value initialization, and usually yields a proper initial value (0 for int, 0.0 for double, calling the default constructor for user defined types that have user declared constructors, ...). This is important especially if your struct is a template.
No, they are not 0 by default. The simplest way to ensure that all values or defaulted to 0 is to define a constructor
Snapshot() : x(0), y(0) {
}
This ensures that all uses of Snapshot will have initialized values.
In general, no. However, a struct declared as file-scope or static in a function /will/ be initialized to 0 (just like all other variables of those scopes):
int x; // 0
int y = 42; // 42
struct { int a, b; } foo; // 0, 0
void foo() {
struct { int a, b; } bar; // undefined
static struct { int c, d; } quux; // 0, 0
}
With POD you can also write
Snapshot s = {};
You shouldn't use memset in C++, memset has the drawback that if there is a non-POD in the struct it will destroy it.
or like this:
struct init
{
template <typename T>
operator T * ()
{
return new T();
}
};
Snapshot* s = init();
In C++, use no-argument constructors. In C you can't have constructors, so use either memset or - the interesting solution - designated initializers:
struct Snapshot s = { .x = 0.0, .y = 0.0 };
Since this is a POD (essentially a C struct) there is little harm in initialising it the C way:
Snapshot s;
memset(&s, 0, sizeof (s));
or similarly
Snapshot *sp = new Snapshot;
memset(sp, 0, sizeof (*sp));
I wouldn't go so far as to use calloc() in a C++ program though.
I believe the correct answer is that their values are undefined. Often, they are initialized to 0 when running debug versions of the code. This is usually not the case when running release versions.
Move pod members to a base class to shorten your initializer list:
struct foo_pod
{
int x;
int y;
int z;
};
struct foo : foo_pod
{
std::string name;
foo(std::string name)
: foo_pod()
, name(name)
{
}
};
int main()
{
foo f("bar");
printf("%d %d %d %s\n", f.x, f.y, f.z, f.name.c_str());
}
I know this question is super old, but this question popped up for me on google and I found this other way and figured I'd add it here:
Snapshot s {};
I'm not sure what C/C++ language version you need for this syntax.