Why this data member is initialized? [duplicate] - c++

This question already has answers here:
Uninitialized values being initialized?
(7 answers)
Closed 8 years ago.
I'm doing some testing...
Firstly I post my source code
the .h file
class Complex{
private:
int r = 0;//initializer
int i ;
public:
Complex(int , int I = 0);
Complex();
void print();
void set(int, int I = 1);
static void print_count();
static int count;
};
the .cpp file
#include <iostream>
#include "complex.h"
int Complex::count = 1;
Complex::Complex(int R , int I){
r = R;
i = I;
count++;
std::cout << "constructing Complex object...count is " << Complex::count << std::endl;
}
Complex::Complex(){//default constructor
std::cout << "default constructor is called..." << std::endl;
}
void Complex::print(){
std::cout << "r = " << r << ';' << "i = " << i << std::endl;
return;
}
void Complex::set(int R, int I /*= 2*/){//will be "redefaulting", an error
r = R;
i = I;
return;
}
void Complex::print_count(){//static
Complex::count = -1;//jsut for signaling...
std::cout << "count is " << count << std::endl;
return;
}
the main function
#include <iostream>
#include "complex.h"
int main(){
Complex d;//using default constructor
d.print();
/*Complex c(4, 5);*/
Complex c(4);
//c.print();
/*c.set(2, 3)*/
c.print();
c.set(2 );
c.print();
std::cout << "count is " << c.count << std::endl;//c can access member data
c.print_count();
c.count++;//
return 0;
}
consider the Complex object d constructed with default ctor
because the data member r is initialized using with 0, when executing d.print(),
r is expected to be 0
and i isn't, so I expected it to be garbage value
but when I'm testing, one strange thing happens.
if I eliminate this and the following lines of code in the main file:
std::cout << "count is " << c.count << std::endl;//c can access member data
then d.print() will give the value of i as 32767 on my system, which I guess it's a garbage value;
but once that line is added, d.print() just give i's value to 0 on my system.
I don't get it. I hasn't set, modiify or initialize i's value, why should it be 0?
or, it is also a garbage value?
or, calling one of those function corrupts the value of i?
how is the thing run behind the scene here?
thx for helping.

0 is just as garbage value as any other. Don't make the mistake of thinking otherwise.
Formally, reading an uninitialized variable is undefined behavior, so there's no point in wondering about it: just fix it by initializing the variable properly.

Related

boost multiarray as class member is not filled

I'm trying to use boost to create a multidimensional array and I want said array to be a member of some class.
However I find two problems with it:
1 - I need to declare the size of the array with
boost::extents[2][2]
Everytime I want to use the array. Otherwise I get the following error:
a.out: /usr/include/boost/multi_array/base.hpp:136: Referenceboost::detail::multi_array::value_accessor_n<T, NumDims>::access(boost::type<Reference>, boost::detail::multi_array::value_accessor_n<T, NumDims>::index, TPtr, const size_type*, const index*, const index*) const [with Reference = boost::detail::multi_array::sub_array<double, 1ul>; TPtr = double*; T = double; long unsigned int NumDims = 2ul; boost::detail::multi_array::value_accessor_n<T, NumDims>::index = long int; boost::detail::multi_array::multi_array_base::size_type = long unsigned int]: Assertion `size_type(idx - index_bases[0]) < extents[0]' failed.
2 - Ok, maybe this is just part of how multidimensional arrays work in C++ with Boost, I'm going to write my code accepting every function "declares" the array. However, if I do this I find the array is empty.
Here's a snippet of code that reproduces this problem. During the "construction" of the class the array should be filled. However, the line
cout << "Result: " << testing.getArrayMember(0,1) << endl;
outputs "Result: 0".
#include <iostream>
#include "boost/multi_array.hpp"
typedef boost::multi_array<double, 2> dbl_array;
using namespace std;
class TestClass {
public:
dbl_array darray;
TestClass(double x);
void fillArray(double x);
double getArrayMember(int i, int j);
};
TestClass::TestClass(double x) {
dbl_array darray(boost::extents[2][2]);
cout << "Class constructor called" << endl;
fillArray(x);
}
void TestClass::fillArray(double x) {
cout << "Filling array" << endl;
dbl_array darray(boost::extents[2][2]); // Without this line, the code fails at runtime
darray[0][0] = x;
darray[1][0] = 2.0*x;
darray[0][1] = 3.0*x;
darray[1][1] = 4.0*x;
cout << "Array filled" << endl;
}
double TestClass::getArrayMember(int i, int j) {
dbl_array darray(boost::extents[2][2]); // Without this line, the code fails at runtime
return darray[i][j];
}
int main() {
TestClass testing = TestClass(5.0);
// The result is 0 in the end
cout << "Result: " << testing.getArrayMember(0,1) << endl;
return 0;
}
What am I doing wrong here?
Option 1 is to use an initialisation list:
TestClass::TestClass(double x) : darray(boost::extents[2][2]) {
cout << "Class constructor called" << endl;
fillArray(x);
}
Since otherwise the member of the class darray is created using the default constructor and not through your line
dbl_array darray(boost::extents[2][2]);
as you believe.
This is the same answers as given in initialize boost::multi_array in a class
However, I want to add the following bit, which I think it is relevant in this situation:
It might be necessary for you to generate the array after performing some kind of operation in the constructor of your class. You can achieve this using "resize" after the array has been created by the default constructor.
Ie, instead of
TestClass::TestClass(double x) {
dbl_array darray(boost::extents[2][2]);
cout << "Class constructor called" << endl;
fillArray(x);
}
you could have
TestClass::TestClass(double x) {
darray.resize(boost::extents[2][2]);
cout << "Class constructor called" << endl;
fillArray(x);
}

How to instantiate a variable from a class with a variable from another class with C++

I'm trying to instantiate a variable Tt1 from a class called ÌnletConditions with the variable Tt0 from another class with the object ein_in.
double InletConditions::Tt1 = ein_in.Tt0;
The variable Tt1 is declared as public static double in the headerfile of the class InletConditions.
class InletConditions {
public:
static double Tt1;
}
The variable Tt0 is declared and instantiated like this:
\\ file Eingabe_Konstanten.h
class Eingabe_Konstanten {
public:
static double Tt0;
}
\\ file Eingabe_Konstanten.cpp
double Eingabe_Konstanten::Tt0 = io_ein.read(1);
io_ein.read(int) refers to a method, which reads in a value from the specified line number (int) from a file. The value should become 293.15.
How can I achieve that the value of Tt1 also becomes 293.15? In the output it is just 0.
int main() {
Eingabe_Konstanten ein;
InletConditions in;
std::cout << ein.Tt0 << endl;
std::cout << in.Tt1 << endl;
}
Output:
293.15
0
I would be pleased if anyone could help me, since I am new to programming and don't know what topic this problem is related to.
Thanks in advance.
Static variables refer to the class itself and not to a particular object of that class. As such you must call them using the scope resolution operator of the class:
InletConditions::Tt1 = Eingabe::Tt0;
std::cout << Eingabe::Tt0 << endl;
std::cout << InletConditions::Tt1 << endl;
LIVE DEMO
Why not just use:
int main() {
Eingabe_Konstanten ein;
InletConditions in;
in.Tt1 = ein.Tt0; //You need to assign the value of ein.Tt0 to in.Tt1 here
std::cout << ein.Tt0 << endl;
std::cout << in.Tt1 << endl;
}

Returning an array in C++ [duplicate]

This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 7 years ago.
I'm trying to learn C++ and had a question about returning arrays in C++. I know that in this case perhaps Vector may be better and that there is no need for a getter method as the fields are visible within the same class but I'm trying to learn about memory management so I'll use them.
class Color {
double r;
double g;
double b;
public:
Color(int a, int aa, int aaa) {
r = a;
g = aa;
b = aaa;
}
bool operator==(const Color &other) {
double *otherCol = other.getter();
return otherCol[0] == r && otherCol[1] == g && otherCol[2] == b;
}
double* getter() const {
double second[3] = {r,g,b};
return second;
}
};
int main() {
Color col1(23, 54, 200);
Color col2(23, 54, 200);
cout << (col1 == col2) << endl;
return 0;
}
This code should print out a 1 if the RGB colors are the same and 0 otherwise. But it does not print a 1. To debug, I added the following lines (twice on purpose) right before the return statement in operator==:
cout << otherCol[0] << " " << otherCol[1] << " " << otherCol[2] << endl;
cout << otherCol[0] << " " << otherCol[1] << " " << otherCol[2] << endl;
Oddly enough, the results are different:
23 54 200
6.91368e-310 6.91368e-310 3.11046e-317
Can someone please tell me what causes this and what would be a reasonable remedy that does not rely on Vector or dynamic allocation of memory? Let's assume that we don't want to pass in an array into getter() to update.
In getter you are returning the address of a local variable which results in undefined behavior so you are getting random memory. If you return a pointer you have to do something like new the variable in the called function and delete it after the function returns.
Or you could make second a class member which would keep it from going out of scope.
You could also pass the array in as a parameter.

Difference between call by address(pointer) and call by reference [duplicate]

This question already has answers here:
What are the differences between a pointer variable and a reference variable?
(44 answers)
Closed 7 years ago.
Can you tell me the difference between the source 1 and 2?
The book says the first one is call by address(pointer) and the second one is call by reference, but i don't exactly get those two sources.
Please explain those sources to me please, thank you in advance.
1.
#include <iostream>
using namespace std;
void absolute(int *a);
void main()
{
int a = -10;
cout << "Value a before calling the main function = " << a << endl;
absolute(&a);
cout << "Value a after calling the main function = " << a << endl;
}
void absolute(int *a)
{
if (*a < 0)
*a = -*a;
}
2.
#include <iostream>
using namespace std;
void absolute(int &a);
void main()
{
int a = -10;
cout << "Value a before calling the main function" << a << endl;
absolute(a);
cout << "Value a after calling the main function" << a << endl;
}
void absolute(int &a)
{
if (a < 0)
a = -a;
}
In terms of what happens at the CPU level, pointers and references are exactly the same. The difference lies in the compiler, it won't let you do a delete on a reference (and there's less typing)
So in your code both functions do the same thing.

Printing a pointer-to-member-field

I was debugging some code involving pointers to member fields, and i decided to print them out to see their values. I had a function returning a pointer to member:
#include <stdio.h>
struct test {int x, y, z;};
typedef int test::*ptr_to_member;
ptr_to_member select(int what)
{
switch (what) {
case 0: return &test::x;
case 1: return &test::y;
case 2: return &test::z;
default: return NULL;
}
}
I tried using cout:
#include <iostream>
int main()
{
std::cout << select(0) << " and " << select(3) << '\n';
}
I got 1 and 0. I thought the numbers indicated the position of the field inside the struct (that is, 1 is y and 0 is x), but no, the printed value is actually 1 for non-null pointer and 0 for null pointer. I guess this is a standard-compliant behavior (even though it's not helpful) - am i right? In addition, is it possible for a compliant c++ implementation to print always 0 for pointers-to-members? Or even an empty string?
And, finally, how can i print a pointer-to-member in a meaningful manner? I came up with two ugly ways:
printf("%d and %d\n", select(0), select(3)); // not 64-bit-compatible, i guess?
ptr_to_member temp1 = select(0); // have to declare temporary variables
ptr_to_member temp2 = select(3);
std::cout << *(int*)&temp1 << " and " << *(int*)&temp2 << '\n'; // UGLY!
Any better ways?
Pointers to members are not as simple as you may think. Their size changes from compiler to compiler and from class to class depending on whether the class has virtual methods or not and whether it has multiple inheritance or not. Assuming they are int sized is not the right way to go. What you can do is print them in hexadecimal:
void dumpByte(char i_byte)
{
std::cout << std::hex << static_cast<int>((i_byte & 0xf0) >> 4);
std::cout << std::hex << static_cast<int>(i_byte & 0x0f));
} // ()
template <typename T>
void dumpStuff(T* i_pStuff)
{
const char* pStuff = reinterpret_cast<const char*>(i_pStuff);
size_t size = sizeof(T);
while (size)
{
dumpByte(*pStuff);
++pStuff;
--size;
} // while
} // ()
However, I'm not sure how useful that information will be to you since you don't know what is the structure of the pointers and what each byte (or several bytes) mean.
Member pointers aren't ordinary pointers. The overloads you expect for << aren't in fact there.
If you don't mind some type punning, you can hack something up to print the actual values:
int main()
{
ptr_to_member a = select(0), b = select(1);
std::cout << *reinterpret_cast<uint32_t*>(&a) << " and "
<< *reinterpret_cast<uint32_t*>(&b) << " and "
<< sizeof(ptr_to_member) << '\n';
}
You can display the raw values of these pointer-to-members as follows:
#include <iostream>
struct test {int x, y, z;};
typedef int test::*ptr_to_member;
ptr_to_member select(int what)
{
switch (what) {
case 0: return &test::x;
case 1: return &test::y;
case 2: return &test::z;
default: return NULL;
}
}
int main()
{
ptr_to_member x = select(0) ;
ptr_to_member y = select(1) ;
ptr_to_member z = select(2) ;
std::cout << *(void**)&x << ", " << *(void**)&y << ", " << *(void**)&z << std::endl ;
}
You get warnings about breaking strict anti-aliasing rules (see this link), but the result is what you might expect:
0, 0x4, 0x8
Nevertheless, the compiler is free to implement pointer-to-member functionality however it likes, so you can't rely on these values being meaningful.
I think you should use printf to solve this problen
#include <stdio.h>
struct test{int x,y,z;}
int main(int argc, char* argv[])
{
printf("&test::x=%p\n", &test::x);
printf("&test::y=%p\n", &test::y);
printf("&test::z=%p\n", &test::z);
return 0;
}