In the below code, I expect members of a being inited with gargabe as they are not mentioned in the members-init-list of the called constructor (with two int parameters). Instead, I'm constantly getting 0 in both i and j of a, b and c and I am failing to see why. Could anybody please point me in the right direction?
#include <iostream>
#include <type_traits>
class A {
public:
int i;
int j;
A() = delete;
A(int a, int b) { std::cout << "VOLOLO!" << std::endl; };
};
int
smear_stack(int p)
{
int j = p++;
int a[500] = {};
for(int i = 0; i < 499; i++) {
a[i] = ++j;
}
std::cout << j << std::endl;
return ++j;
}
int main(void)
{
int i = 2;
i = smear_stack(++i);
A a (i, 32 );
std::cout << "a is " << a.i << " " << a.j << std::endl;
A b = { a };
std::cout << "b is " << b.i << " " << b.j << std::endl;
A c = { a.i, a.j };
std::cout << "c is " << c.i << " " << c.j << std::endl;
}
The i and j fields that you are accessing are, indeed, uninitialized. However, you are smearing the wrong part of the stack. It just so happens that on most OSes, the stack is initially all zeros. It even used to be common in C (long ago) to assume that automatic variables in main were zero-initialized.
To see that the memory is indeed uninitialized, it suffices to put something else there. Here's an example:
#include <iostream>
#include <memory>
class A {
public:
int i;
int j;
A() = delete;
A(int a, int b) { std::cout << "VOLOLO!" << std::endl; };
};
union U {
int is[2];
A a;
U() : is{3,4} {}
};
int
main()
{
U u;
std::construct_at(&u.a, 5, 6);
std::cout << u.a.i << ", " << u.a.j << std::endl;
// output:
// VOLOLO!
// 3, 4
}
Related
i'm doing an online c++ learning course with quiz. The last output line of this snippet is to be determined (comments added by me). Correct answer: 10. My question: why 10 and not 11?
Calling a(b) swaps the two variables, so why is the last a.a.b 0 and not 1? / Why does the a.b() in cout not affect the a.a.b?
#include <iostream>
using namespace std;
class classA {
public:
classA() { st.f = st.p = 1; }
struct { int f, p; } st;
int bfunc(void);
};
int classA::bfunc(void) { int x = st.f; st.f = st.p; st.p = x; return x; };
int main()
{
classA a;
a.st.f = 0;
cout << a.st.f << a.st.p << endl; //01
a.bfunc();
cout << a.st.f << a.st.p << endl; //10
a.bfunc();
cout << a.st.f << a.st.p << endl; //01
a.bfunc();
cout << a.st.f << a.st.p << endl; //10
cout << a.bfunc() << a.st.p << endl; //10
return 0;
}
If static variables has only one copy for the program. So why is it not possible to swap 2 numbers using another function?
Code:
#include <iostream>
void swap(int, int);
int main()
{
static int a = 1;
static int b = 2;
swap(a, b);
std::cout << "a = " << a << std::endl << "b = " << b << std::endl;
std::cin.get();
}
void swap(int a,int b)
{
int temp = a;
a = b;
b = temp;
std::cout << "a = " << a << std::endl << "b = " << b << std::endl;
}
As the 'swap' function is taking parameters as pass by value, copies of the variables are passed to the swap function which will only swap its local variables 'a' and 'b' (passed as parameter) not the static ones passed from main.
Swap should be taking parameters as references like below.
#include <iostream>
void swap(int&, int&);
int main()
{
static int a = 1;
static int b = 2;
swap(a, b);
std::cout << "a = " << a << std::endl << "b = " << b << std::endl;
std::cin.get();
}
void swap(int &a,int &b)
{
int temp = a;
a = b;
b = temp;
std::cout << "a = " << a << std::endl << "b = " << b << std::endl;
}
Please note that static variable defined in a function pertains its value in the subsequent calls of the function in which it is declared.
This is because you are passing arguments by value and not by address(reference). Your function is working on a copy of a and a copy of b - not the original values. You could try this(notice the & in the function prototype and function definition arguments)
void swap(int &, int &);
void swap(int& a, int& b)
{
int temp = a;
a = b;
b = temp;
std::cout << "a = " << a << std::endl << "b = " << b << std::endl;
}
I have a problem in using auto declarations. I write a program in Visual Studio 2017 as follow:
#include "stdafx.h"
#include <stdio.h>
#include <iostream>
#include <vector>
using namespace std;
class MyClass
{
public:
struct mystruct {
vector<int> vi;
};
vector<mystruct> TheStructV;
void AddStructV() {
TheStructV.push_back(mystruct());
};
};
int main()
{
MyClass MyObj[3];
for (int a = 0; a < 3; a++) {
MyObj[a].AddStructV();
for (int i = 1; i <= 5; i++) {
MyObj[a].TheStructV[MyObj[a].TheStructV.size() - 1].vi.push_back(i * 10 + idx);
}
idx++;
}
for (int b = 0; b<3; b++) {
cout << "MyObj[" << b << "] struct vector size:" << MyObj[b].TheStructV.size() << endl;
cout << "MyObj[" << b << "] struct vi size:" << MyObj[b].TheStructV[0].vi.size() << endl;
}
for (int i = 0; i < 3; i++) {
cout << "MyObj[" << i << "].vi:";
for (int j = 0; j < 5; j++) {
cout << MyObj[i].TheStructV[0].vi[j] << "-";
}
cout << endl;
}
return 0;
}
It works as expected, and the output is:
MyObj[0] struct vector size:1
MyObj[0] struct vi size:5
MyObj[1] struct vector size:1
MyObj[1] struct vi size:5
MyObj[2] struct vector size:1
MyObj[2] struct vi size:5
MyObj[0].vi:11-21-31-41-51-
MyObj[1].vi:12-22-32-42-52-
MyObj[2].vi:13-23-33-43-53-
However, if I change the code to this:
#include "stdafx.h"
#include <stdio.h>
#include <iostream>
#include <vector>
using namespace std;
class MyClass
{
public:
struct mystruct {
vector<int> vi;
};
vector<mystruct> TheStructV;
void AddStructV() {
TheStructV.push_back(mystruct());
};
};
int main()
{
MyClass MyObj[3];
int idx = 1;
for (auto M : MyObj) {
M.AddStructV();
for (int i = 1; i <= 5; i++) {
M.TheStructV[M.TheStructV.size() - 1].vi.push_back(i * 10 + idx);
}
idx++;
}
for (int b = 0; b<3; b++) {
cout << "MyObj[" << b << "] struct vector size:" << MyObj[b].TheStructV.size() << endl;
cout << "MyObj[" << b << "] struct vi size:" << MyObj[b].TheStructV[0].vi.size() << endl;
}
idx = 1;
for (auto MC : MyObj) {
cout << "MyObj[" << idx - 1 << "].vi:";
for (auto thisStruct : MC.TheStructV) {
cout << thisStruct.vi[0] << "-";
cout << thisStruct.vi[1] << "-";
cout << thisStruct.vi[2] << "-";
cout << thisStruct.vi[3] << "-";
cout << thisStruct.vi[4] << "-";
}
cout << endl;
idx++;
}
return 0;
}
It compiles without problem, but I get an error when I run it, and the output is:
MyObj[0] struct vector size:0
The program is stuck here.
It seems that I am missing something. I even tried replacing auto M with MyClass M, but still the same problem.
This line will make a copy of your object
for (auto M : MyObj)
change it to a reference so you can modify it
for (auto& M : MyObj)
Objects (that are not dynamic) are blocks of data in memory.
Is there a way to cycle through and print each item in an object?
I tried doing it with 'this' but I keep getting errors.
#include "stdafx.h"
#include <iostream>
#include "TestProject.h"
using namespace std;
class myclass {
int someint = 10;
double somedouble = 80000;
int somearray[5] = {0, 1, 2, 3, 4};
public:
void somefunction();
};
void myclass::somefunction() {
cout << "\n test \n" << this;
myclass *somepointer;
somepointer = this;
somepointer += 1;
cout << "\n test2 \n" << *somepointer;
//Error: no opperator '<<' matches these operands
}
int main() {
myclass myobject;
myobject.somefunction();
return 0;
}
I'm guessing the error is because the types don't match. But I can't really figure a solution. Is there a dynamic type, or do I have to test the type somehow?
You must add friend global std::ostream operator << to display content of object
#include "stdafx.h"
#include <iostream>
using namespace std;
class myclass {
int someint;
double somedouble;
int somearray[5];
public:
myclass()
{
someint = 10;
somedouble = 80000;
somearray[0] = 0;
somearray[1] = 1;
somearray[2] = 2;
somearray[3] = 3;
somearray[4] = 4;
}
void somefunction();
friend std::ostream& operator << (std::ostream& lhs, const myclass& rhs);
};
std::ostream& operator << (std::ostream& lhs, const myclass& rhs)
{
lhs << "someint: " << rhs.someint << std::endl
<< "somedouble: " << rhs.somedouble << std::endl
<< "somearray: { ";
for (int iIndex = 0; iIndex < 5; iIndex++)
{
if (iIndex == 4)
lhs << rhs.somearray[iIndex] << " }" << std::endl;
else
lhs << rhs.somearray[iIndex] << ", ";
}
return lhs;
}
void myclass::somefunction() {
cout << "\n test \n" << this;
myclass *somepointer;
somepointer = this;
somepointer += 1; // wrong pointer to object with `object + sizeof(object)` address,
// data probably has been corrupted
cout << "\n test2 \n" << *somepointer; // displaying objects content
}
int main() {
myclass myobject;
myobject.somefunction();
return 0;
}
as you want to get to the object member using its pointers shifts I post another program
#include "stdafx.h"
#include <iostream>
using namespace std;
#pragma pack (push, 1) // force data alignment to 1 byte
class myclass {
int someint;
double somedouble;
int somearray[5];
public:
myclass()
{
someint = 10;
somedouble = 80000;
somearray[0] = 0;
somearray[1] = 1;
somearray[2] = 2;
somearray[3] = 3;
somearray[4] = 4;
}
void somefunction();
friend std::ostream& operator << (std::ostream& lhs, const myclass& rhs);
};
#pragma pack (pop) // restore data alignment
std::ostream& operator << (std::ostream& lhs, const myclass& rhs)
{
lhs << "someint: " << rhs.someint << std::endl
<< "somedouble: " << rhs.somedouble << std::endl
<< "somearray: { ";
for (int iIndex = 0; iIndex < 5; iIndex++)
{
if (iIndex == 4)
lhs << rhs.somearray[iIndex] << " }" << std::endl;
else
lhs << rhs.somearray[iIndex] << ", ";
}
return lhs;
}
void myclass::somefunction() {
int* pSomeInt = (int*)this; // get someint address
double *pSomeDouble = (double*)(pSomeInt + 1); // get somedouble address
int* pSomeArray = (int*)(pSomeDouble + 1); // get somearray address
std::cout << "someint: " << *pSomeInt << std::endl
<< "somedouble: " << *pSomeDouble << std::endl
<< "somearray: { ";
for (int iIndex = 0; iIndex < 5; iIndex++)
{
if (iIndex == 4)
std::cout << pSomeArray[iIndex] << " }" << std::endl;
else
std::cout << pSomeArray[iIndex] << ", ";
}
}
int main() {
myclass myobject;
myobject.somefunction();
return 0;
}
C++, by design, has no reflection feature. This means there is no generic, type-independent way to acces type metadata (e.g. the list of members if a class and their types) at runtime. So what you're trying to do (if I understand it correctly) cannot be done in C++.
Also I'm not sure what you meant by "objects (that are not dynamic)". all objects are blocks of data in memory, regardless of whether they are dynamically allocated or not.
Why do I get different output? How can I fix this? I want the trainingVector[0] to reference A.
vector<double> A(4,0);
vector<vector<double > > trainingVector;
A[0]=1;
trainingVector.push_back(A);
A[0]=2;
cout << A[0] << endl ;
cout << trainingVector[0][0] << endl ;
You cannot store references in STD containers, so what you ask for is impossible. If you want trainingVector to store a pointer to A, that's entirely doable:
vector<double> A(4,0);
vector<vector<double>*> trainingVector;
A[0] = 1;
trainingVector.push_back(&A);
A[0] = 2;
// notice that you have to dereference trainingVector[0] to get to A
cout << (*trainingVector[0])[0] << endl; // prints 2
You could store a pointer to A instead:
#include <iostream>
#include <vector>
int main()
{
std::vector<int> A(1);
A[0] = 1;
std::vector<std::vector<int>*> trainingVector;
trainingVector.push_back(&A);
A[0] = 2;
std::cout << A[0] << std::endl;
std::cout << (*trainingVector[0])[0] << std::endl;
return 0;
}
Alternatively, if you really want the syntax as specified in the question, you could do something like this:
#include <iostream>
#include <vector>
template <typename T>
class VecRef
{
private:
std::vector<T> *m_v;
public:
VecRef(std::vector<T>& v)
: m_v(&v)
{}
T& operator[](int i)
{
return (*m_v)[i];
}
};
int main()
{
std::vector<int> A(1);
A[0] = 1;
std::vector<VecRef<int>> trainingVector;
trainingVector.push_back(A);
A[0] = 2;
std::cout << A[0] << std::endl;
std::cout << trainingVector[0][0] << std::endl;
return 0;
}