Classes and Dynamic Memory - c++

I'm a little confused trying to understand what is happening here:
#include <iostream>
using namespace std;
class Point
{
int x, y;
public:
Point(): x(0), y(0) {}
int getX() {return x;}
int getY() {return y;}
};
int main(int argc, char const *argv[])
{
Point *a = new Point[2];
Point *b = a;
for (int i = 0; i < 5; i++, a++)
cout << a->getX() << "," << a->getY() << endl;
delete[] b;
return 0;
}
Output:
0,0
0,0
0,0
1041,0
825503793,667692
This is just an experiment, I looked at this when I was practicing with classes and dynamic memory.
Why the output look like this, what is happening behind?
I'm sure than the 2 first Point will be initialized with the Point() constructor, so why the third is also 0,0?
And why the other 2 have that random numbers, where are that objects allocated? Are there just random memory / uninitialized memory of Point type?

Related

C++ ints getting corrupted, generated with rand()

I'm attempting to write a C++ program that uses a Point class consisting of x and y coordinates (ints) and a boolean. The x and y coordinates should be in the range from 0-100, but upon execution and with a print statement to test, the values printed out are corrupted.
My code looks like this:
int main(int argc, const char * argv[]) {
vector<Point> points;
for (int i = 0; i<200; i++) {
int rand_X = (rand() % 100) + 1;
int rand_Y = (rand() & 100) + 1;
Point point = Point(rand_X, rand_Y, false);
cout<< point.getX() << " " << point.getY() << endl;
points.push_back(point);
}
return 0;
and the Point class looks like this, if that's relevant:
struct Point {
public:
int x;
int y;
bool in_layer;
Point(int x, int y, bool in_layer) {}
int getX() {return this->x;}
int getY() {return this->y;}
};
And the output is just "-272632592 32766" repeated 200 times, which I'm assuming is a corrupted value.
Any ideas what could be causing the issue?
Your constructor didn't do anything, which contribute to an UB when you call getX getY methods. Plus, I think there's no need to use constructor and getx gety methods here.
If that's a code for learning, you may need to assign to the member x, y in the constructor or use the folowing technique (initialization list):
Point(int _x, int _y, bool _in_layer) : x(_x), y(_y), in_layer(_in_layer){}

Converting C++ code to C, array of structs

I'm converting C++ code to C for an exercise (we are just learning c++ now), and I am lost at this part.
First, the c++ code:
Point()
{
x = y = 0;
}
main()
{
const int N = 200;
Point *A = new Point[N], sum;
}
Here's my C version of it:
struct Point //constructor
{
int x;
int y;
} Point;
main()
{
int N = 200;
Point* A = malloc(N * sizeof(*Point[]));
}
That should give you an idea of what I'm trying to do. Questions:
Is sum in the C++ code the C++ sum function, or is it aPointstruct`?
For allocating the memory in C, I don't think my method works. Should I do a for loop where it mallocs each index of A[]? (A should be an array of Point structs).
Any assistance would be greatly appreciated.
EDIT: Got asked for the context of the code.
Here's the whole C++ program:
#include <iostream>
// a point on the integer grid
struct Point
{
// constructor
Point()
{
x = y = 0;
}
// add point componentwise
void add(const Point &p)
{
x += p.x;
y += p.y;
}
// print to standard output
void print() const
{
std::cout << "[" << x << "," << y << "]" << std::endl;
}
// data
int x, y;
};
int main()
{
const int N = 200;
Point *A = new Point[N], sum;
for (int i=0; i < N; ++i) {
sum.print();
A[i].x = i; A[i].y = -i;
sum.add(A[i]);
}
sum.print();
delete [] A;
}
Ultimately, I have to emulate that in C. Currently stuck at the question I asked: re: what does that line do. I have since figured out that I need to make a struct of Point called sum, and print that after running the add function on all its members.
In your C version:
struct Point //constructor
{
int x;
int y;
} Point;
should be:
typedef struct //constructor
{
int x;
int y;
} Point;
Because in your case, you defined a global variable named Point.
And, the C programming language has the const keyword as C++ as well, so you can do this in the C language:
const int N = 200;
And the C++ code:
Point *A = new Point[N], sum;
In C version, should be:
Point *A = malloc(N * sizeof(Point)), sum;
But in this version, the memory isn't initialized by zero.
You can use the calloc function instead of the malloc to allocate memory and initialize it with zero:
Point *A = calloc(N, sizeof(Point)), sum;
Then back to your question:
Is sum in the c++ code the c++ sum function, or is it a Point struct?
It is a Point type variable.
For allocating the memory in C, I don't think my method works. Should I do a for loop where it mallocs each index of A[]? (A should be an array of Point structs).
No, there's no necessary to write a for loop. The malloc function will do exactly what you want.
Is sum in the c++ code the c++ sum function, or is it a Point struct?
In your case, it is a Point struct.
Point *A = new Point[N], sum;
is equivalent to:
Point *A = new Point[N];
Point sum; //I have no idea why naming is sum
If you need Point* for sum, you should write it in the following way:
Point *A = new Point[N], *sum;
For allocating the memory in C, I don't think my method works
It does not work, syntax is wrong. Try:
EDIT: thanks to #mch, you should not use cast for malloc.
typedef struct Point Point;
Point* A = malloc(N * sizeof(Point));

Take item position in vector with structure

Let see code:
struct tmp {
int a;
std::vector <second_struct> b;
}
struct second_struct {
int x;
int y;
}
//main.cpp
int main {
std::vector<tmp> test;
(...); //push data to test
}
So when i push data to test, in second function i want to get vector "b" from this vector 'test'. And find vector b by a;
(i.e I have int a and std::vector<tmp> test; , dont have std::vector <second_struct> b;(from vector test) and want to get it. (vector test is a big array, so i need to do it fastest and using little power )
How to do that? (i suppose std::map will be better? But if you tell me yes, tell me too how to do that in std::Vector)
Loop through test vector checking if tmp::a member is equal to your int a. If so, you have your vector<second_struct> b
for (int i=0;i<test.size();i++) {
if (test[i].a == a) {
// do whatever you need to do with test[i].b
break;
}
}
P.S. map would be easier, just
std::map<int, std::vector<second_struct>> map;
//insert data
std::vector<second_struct> b = map[a]; //assuming it's a that you're looking for
The most straightforward approach is to use map (or unordered_map in C++11). Hope this full example helps:
#include <map>
#include <vector>
#include <iostream>
struct str {
str(int _x, int _y) : x(_x), y(_y) {}
int x, y;
};
std::map<int, std::vector<str> > test;
int main() {
std::vector<str> vec;
for (int i = 0; i < 100; ++i) {
vec.clear();
vec.push_back(str(i, 2 * i));
vec.push_back(str(i + 1, i + 2));
test[i] = vec;
}
std::vector<str> result;
// get some element
result = test[10];
std::cout << "Found at position 10:\n";
for (int i = 0; i < result.size(); ++i)
std::cout << result[i].x << ' ' << result[i].y << '\n';
return 0;
}

Why does this program create an output like this?

Why does this program write 45, 125 and 300?
I know for 45 and 300, I'm more interested in a case sum1(arrD), where program writes 125.
I hope somebody will know.
#include <iostream>
using namespace std;
class B{
public:
B(): b(bCounter++){}
int b;
static int bCounter;
};
int B::bCounter = 0;
class D : public B{
public:
D() : d(bCounter){}
int d;
};
const int N = 10;
B arrB[N];
D arrD[N];
int sum1(B* arr){
int s = 0;
for (int i=0; i<N; i++) s+=arr[i].b;
return s;
}
int sum2 (D* arr){
int s = 0;
for (int i = 0; i<N; i++) s+= arr[i].b + arr[i].d;
return s;
}
int main(){
cout<<" result is: "<<sum1(arrB)<<endl;
cout<<" result is: "<<sum1(arrD)<<endl;
cout<<" result is: "<<sum2(arrD)<<endl;
system("pause");
return 0;
}
The static arrays B arrB[N] and D arrD[N] seem to be causing the trouble here.
Arrays aren't polymorphic; you can pass a D* to a function expecting a B* only if it expects a single element. (Try using std::vector, and you'll get a compile time error.) The reason is simple: the pointer arithmetic needed to access the array elements is based on the static size of the pointed to element, so each time you do i++ in the loop in sum1, and then index, the compiler calculates the address of your element as arr + i * sizeof(B) (at the machine level, where arr is a pure, untyped address).
Trying to do pointer arithmetic when the static type is not the same as the dynamic type is undefined behavior, so as far as the language is concerned, anything can happen.
And this is yet another reason not to use C style arrays.
The problem is that the arrays do not contain pointers to the objects but whole objects.
So when you use the D array via a pointer to the base class, (as James noted) the behaviour is undefined.
What in practice probably happens on most systems: The pointer-based loop only iterates over half the D objects, because a B object contains only one int, while the D objects contain two of them.
So the loop looks only at the first 5 D objects:
b / d
10/11
11/12
12/13
13/14
14/15
which sums up to the ominous 125.
I think it's incorrect to cast an array of D to an array of B. The stride isn't correct. This is why you see these repeats of values.
Run following code , you'll know the reason
#include <iostream>
using namespace std;
class B{
public:
B(): b(bCounter++){
cout<<"B called\n";
}
int b;
static int bCounter;
};
int B::bCounter = 0;
class D : public B{
public:
D() : d(bCounter){
cout<<"D called\n";
}
int d;
};
const int N = 10;
B arrB[N];
D arrD[N];
int sum1(B* arr){
int s = 0;
for (int i=0; i<N; i++)
{
cout<<arr[i].b<<"\n";
s+=arr[i].b;
}
return s;
}
int sum2 (D* arr){
int s = 0;
for (int i = 0; i<N; i++) s+= arr[i].b + arr[i].d;
return s;
}
int main(){
//cout<<" result is: "<<sum1(arrB)<<endl;
cout<<" result is: "<<sum1(arrD)<<endl;
//cout<<" result is: "<<sum2(arrD)<<endl;
system("pause");
return 0;
}

Is there a way to initialize an array with non-constant variables? (C++)

I am trying to create a class as such:
class CLASS
{
public:
//stuff
private:
int x, y;
char array[x][y];
};
Of course, it doesn't work until I change int x, y; to
const static int x = 10, y = 10;
Which is impractical, because I am trying to read the values of x and y from a file. So is there any way to initialize an array with non-contant values, or declare an array and declare its size on different statements? And I know this would probably require the creation of an array class, but I'm not sure where to start on this, and I don't want to create a 2D dynamic list when the array itself is not dynamic, just the size is not known at compile-time.
use vector.
#include <vector>
class YourClass
{
public:
YourClass()
: x(read_x_from_file()), y(read_y_from_file())
{
my_array.resize(x);
for(int ix = 0; ix < x; ++ix)
my_array[ix].resize(y);
}
//stuff
private:
int x, y;
std::vector<std::vector<char> > my_array;
};
The compiler need to have the exact size of the class when compiling, you will have to use the new operator to dynamically allocate memory.
Switch char array[x][y]; to char** array; and initialize your array in the constructor, and don't forget to delete your array in the destructor.
class MyClass
{
public:
MyClass() {
x = 10; //read from file
y = 10; //read from file
allocate(x, y);
}
MyClass( const MyClass& otherClass ) {
x = otherClass.x;
y = otherClass.y;
allocate(x, y);
// This can be replace by a memcopy
for( int i=0 ; i<x ; ++i )
for( int j=0 ; j<x ; ++j )
array[i][j] = otherClass.array[i][j];
}
~MyClass(){
deleteMe();
}
void allocate( int x, int y){
array = new char*[x];
for( int i = 0; i < y; i++ )
array[i] = new char[y];
}
void deleteMe(){
for (int i = 0; i < y; i++)
delete[] array[i];
delete[] array;
}
MyClass& operator= (const MyClass& otherClass)
{
if( this != &otherClass )
{
deleteMe();
x = otherClass.x;
y = otherClass.y;
allocate(x, y);
for( int i=0 ; i<x ; ++i )
for( int j=0 ; j<y ; ++j )
array[i][j] = otherClass.array[i][j];
}
return *this;
}
private:
int x, y;
char** array;
};
*EDIT:
I've had the copy constructor
and the assignment operator
Not in that manner, as in c++, c-style array sizes have to be known at compile time, with some vendor specific extensions allowing certain runtime sizes (to enhance compatibility with C99), but not in the situation you are describing (if you are interested, here's a description). The easiest thing to do would be:
std::vector< std::vector<char> > array;
And apply the size in the constructor:
array.resize(x);
for(std::vector< std::vector<char> >::iterator curr(array.begin()),end(array.end());curr!=end;++curr){
curr->resize(y);
}
There are many advantages of vector over c style arrays, see here
Put all the memory into one block.
Because it is private you can then get your access methods to retrieve the correct value.
Quick example:
#include <vector>
#include <iostream>
class Matrix
{
public:
class Row
{
public:
Row(Matrix& p,unsigned int x)
:parent(p)
,xAxis(x)
{}
char& operator[](int yAxis)
{
return parent.data(xAxis,yAxis);
}
private:
Matrix& parent;
unsigned int xAxis;
};
Matrix(unsigned int x,unsigned int y)
:xSize(x)
,ySize(y)
,dataArray(x*y)
{}
Matrix::Row operator[](unsigned int xAxis)
{
return Row(*this,xAxis);
}
char& data(unsigned int xAxis,unsigned int yAxis)
{
return dataArray[yAxis*xSize + xAxis];
}
private:
unsigned int xSize;
unsigned int ySize;
std::vector<char> dataArray;
};
int main()
{
Matrix two(2,2);
two[0][0] = '1';
two[0][1] = '2';
two[1][0] = '3';
two[1][1] = '4';
std::cout << two[1][0] << "\n";
std::cout << two.data(1,0) << "\n";
}
Take a look at boost::multi_array.
You can't allocate or initialize a global or static array declaratively using non-constant values (compile-time). It's possible for local arrays though (C99 variable sized arrays, as their initializer essentially runs at runtime every time the function is executed).
For your situation, I suggest using a pointer instead of an array and create the actual array dynamically at runtime (using new):
class CLASS
{
public:
CLASS(int _x, int _y) : x(_x), y(_y) {
array = new char*[x];
for(int i = 0; i < x; ++i)
array[i] = new char[y];
}
~CLASS() {
for (int i = 0; i < x; ++i)
delete[] array[i];
delete[] array;
}
//stuff
private:
int x, y;
char **array;
};
You can allocate memory to your 2-dimensional array in the constructor and free it in the destructor. The simplest way:
array = (char **)malloc(sizeof(char *) * x);
if (array) {
for (i = 0; i < x; i++) {
array[i] = (char *)malloc(sizeof(char) * y);
assert(array[i]);
}
}
If the size is not known at compile time, the array is dynamic. What you could do to keep it static is to make them larger than your largest expected size.
If you want a dynamically sized array as a class member, you need to array new it and assign that value to a pointer. The char array[size] syntax is only for statically-sized arrays.
Better yet, you really should use an std::vector< std::vector<char> >, there are very few good reasons to manually work with dynamically sized arrays these days.