Why does this program create an output like this? - c++

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;
}

Related

error: cannot convert ‘int (*)[4]’ to ‘int**’ | SWAPPING ARRAYS

I am trying to write a function that swap two arrays in O(1) time complexity. However, when i try to write the function parameters, I get the error:
error: cannot convert ‘int (*)[4]’ to ‘int**’
Here is my code:
#include <iostream>
using namespace std;
void swap_array_by_ptr(int* a[], int* b[]) {
int* temp = *a;
*a = *b;
*b = temp;
}
int main()
{
int fr[] = {1,2,3,4};
int rv[] = {4,3,2,1};
swap_array_by_ptr(&fr, &rv);
for (int i = 0; i < 4 ; i++) {
cout << fr[i] << " ";
}
cout << endl;
for (int i = 0; i < 4 ; i++) {
cout << rv[i] << " ";
}
}
However, when i tried to define the arrays with 'new' command, this works as expected as below:
#include <iostream>
using namespace std;
void swap_array_by_ptr(int** a, int** b) {
int* temp = *a;
*a = *b;
*b = temp;
}
int main()
{
int fr = new int[4]{1,2,3,4};
int rv = new int[4]{4,3,2,1};
swap_array_by_ptr(&fr, &rv);
for (int i = 0; i < 4 ; i++) {
cout << fr[i] << " ";
}
cout << endl;
for (int i = 0; i < 4 ; i++) {
cout << rv[i] << " ";
}
}
Is there any way that i can define the arrays with [] method and swap the arrays by sending these arrays with '&array' method ?
As I believe, there must be a way to do that, I only achieve this when I'm trying to do with 'new' method. However, is there any way to swap two arrays in O(1) complexity with sending parameters as
swap_array_by_ptr(&fr, &rv);
?
Thanks for help.
You can not swap two arrays with O( 1 ). You need to swap each pairs of corresponding elements of two arrays.
In the first program
int fr[] = {1,2,3,4};
int rv[] = {4,3,2,1};
swap_array_by_ptr(&fr, &rv);
the expressions &fr and &rv have type int( * )[4] while the corresponding function parameters in fact has the type int **
void swap_array_by_ptr(int* a[], int* b[]) {
after adjusting the parameters having array types to pointers to the array element types by the compiler.
So the compiler issues an error.
You could use standard function std::swap declared in the header <utility> the following way
std::swap( fr, rv );
But in any case its complexity is O( n ).
In the second program there are at least typos. Instead of
int fr = new int[4]{1,2,3,4};
int rv = new int[4]{4,3,2,1};
you have to write
int *fr = new int[4]{1,2,3,4};
int *rv = new int[4]{4,3,2,1};
In this case you are not swapping arrays themselves. That is the arrays will still store their initial values. You are swapping pointers that point to the dynamically allocated arrays.
To be sure that arrays are not swapped consider the following demonstration program.
#include <iostream>
using namespace std;
void swap_array_by_ptr(int** a, int** b) {
int* temp = *a;
*a = *b;
*b = temp;
}
int main()
{
int fr[] = { 1,2,3,4};
int rv[] = {4,3,2,1};
int *p1 = fr;
int *p2 = rv;
swap_array_by_ptr( &p1, &p2 );
for (int i = 0; i < 4 ; i++) {
cout << p1[i] << " ";
}
cout << endl;
for (int i = 0; i < 4 ; i++) {
cout << p2[i] << " ";
}
cout << endl;
for (int i = 0; i < 4 ; i++) {
cout << fr[i] << " ";
}
cout << endl;
for (int i = 0; i < 4 ; i++) {
cout << rv[i] << " ";
}
cout << endl;
}
It is a syntactic quirk inherited from C that a declaration of a function parameter as an array is automatically converted to a declaration as a corresponding pointer. This is not as odd as it might first seem, however, because it dovetails with the automatic conversion of function arguments of array type to corresponding pointers, also inherited from C.*
Thus, this declaration ...
void swap_array_by_ptr(int* a[], int* b[]) {
... is equivalent to this one:
void swap_array_by_ptr(int **a, int **b) {
. But the arguments you are passing do not match. This, for example,
int fr[] = {1,2,3,4};
declares fr as an array of 4 int. If it were passed as a function argument, it would be automatically converted to a pointer to the first element, thus of type int *. Types int * and int ** are not compatible.
On the other hand, what you actually try to pass, &fr is the address of an array 4 int, of type int(*)[4]. This also is incompatible with int **, because arrays are not pointers.
You could write your function like this:
void swap_array_by_ptr(int (*a)[4], int (*b)[4]) {
int temp[4];
memcpy(temp, a, sizeof(a));
memcpy(a, b, sizeof(b));
memcpy(b, temp, sizeof(temp));
}
That would be compatible with the call in your code. Do note, however, that that is specific to array size 4, and you're not really gaining anything useful from that. You could, however, convert it to a template:
template<class T, std::size_t n>
void swap_array(T (*a)[n], T (*b)[n]) {
T temp[n];
memcpy(temp, a, sizeof(a));
memcpy(a, b, sizeof(b));
memcpy(b, temp, sizeof(temp));
}
That handles arrays of any element type and size,** as long as the sizes match. Of course, it scales as O(N) with array size, in both time and auxiliary space.
Such time scaling is unavoidable. To swap two objects you need to read each at least once and write each at least once, and that requires time proportional to the size of the objects. But you could reduce the space overhead to O(1) by swapping the arrays element by element in a loop. That would very likely be slower, but the time complexity would still be O(N).
Of course, you can also use std::swap() on arrays. It is quite similar to the template above, but uses references to the arrays instead of pointers to them.
*This is a specific case of a much more general behavior.
**So long as the temporary array does not turn out to be too large for the stack.
Change the swap_array_by_ptr function from 'swap_array_by_ptr(int** a, int** b)'
to 'swap_array_by_ptr(int* a, int* b)'.
void swap_array_by_ptr(int* a, int* b) {
int* temp = *a;
*a = *b;
*b = temp;
}
here's a link to a similar question: Swapping 2 arrays in C

What ways are there to call a constructor in C++?

//I have a for loop that should construct an array of a certain class "Line" from two arrays of floats
for (int i=0; i<length; i++) Linearray[i](a[i], b[i]);
//my constructor function for line is:
pine::pine(float a, float b) {
st = a;
e = b;
}
//the error I'm getting is that I have no call operator defined.
//It's a little complicated to explain, so say all I can use is this constructor to fill that array.
//also assume arrays a and b are full of floats.
This Linearray[i](a[i], b[i]); tries to call the call operator operator()() (see also What are C++ functors and their uses?) from the Line class (which you probably haven't defined, hence the error) at the ith element in that list. You'd need to assign a new instance to call a constructor there:
Linearray[i] = Line(a[i], b[i]);
Although your question is already answered by Timo. Here is another way to achieve same goal
#include <iostream>
using namespace std;
class Line{
private:
int start, end;
public:
Line(){}
Line(float a, float b) {
start = a;
end = b;
}
};
int main() {
std::cout << "Hello World!\n";
int N = 5;
Line * arr = (Line*)malloc(sizeof(Line) * N);
for(auto i=0; i<N; i++){
arr[i] = Line(5,6);
}
}

return a matrix of integers

Hi I'm creating a Matrix object which is a containter for an int[3][3].
I want to add a get_matrix() function which returns the object itself or the pointer to it, but I'm not able.
eclipse says :
Type cannot convert ‘int (*)[3][3]’ to ‘int**’
enter code here
class Matrix
{
private:
int matrix[3][3];
public:
void set_matrix()
{
int c, d;
printf("Enter the elements of first matrix1\n");
for (c = 0; c < n_rows; c++)
for (d = 0; d < n_column; d++)
scanf("%d", &matrix[c][d]);
}
int get_matrix(){
return matrix;
}
void output_matrix()
{
int c, d;
for (c = 0; c < n_rows; c++) {
printf("\n");
for (d = 0; d < n_column; d++)
printf("%d\t", matrix[c][d]);
}
}
};
Try this:
int **get_matrix() const {
return reinterpret_cast<int **>(matrix);
}
or this:
int **get_matrix() const {
return (int **) matrix;
}
A two dimensioned array cannot be implicitly converted to a pointer to a pointer to an int, although there are several similarities between the two. You can, however, force a cast to an int **.
You could also (and probably should) use a C++ container that is readily available instead of trying to reinvent the wheel.

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));

Performance issue with vectors

I am using a couple of structs in my code. The first struct is constructed after reading data from a line of text file and the second struct contains a vector of structs of the first kind.
struct A{
long a, b, c, d, e, f;
string x, y, z;
}
struct B{
string id1;
vector<A> aVec;
}
Now I read my file and initialize a vector of struct B's. Then based on what the incoming new line's id1 and id2 are, I create a new A and push it into the correct B.
vector<B> bVec;
vector<A> atmpVec;
B btmp;
//Initializing bVec
for(int i = 0; i < 7; i++)
{
btmp.id1 = "c"+to_string(i);
btmp.aVec = atmpVec;
//tried using reserve too.
//btmp.aVec.reserve(50000);
bVec.push_back(btmp);
}
//readerCode
while(getline(file, line))
{
A = readA(line); //readA reads and sets the fields of struct A.
int idx = getBIdx(bVec, A); //getBIdx returns which B struct should i be using.
bVec[idx].aVec.push_back(A);
}
Now the last line has become a bottleneck. If I simply declare a vector of A and keep on pushing back to it, the time taken to process a million records is ~10 seconds.
On the other hand, with this approach, it takes 60 seconds to just process 50k records.
Is there a way I can keep the above general structure without losing the performance.
Any ways to efficiently implement this?
Isn't the time spent in the getBIdx method ? Pushing to a single vector or one between N should be almost the same.
Trying with a simple getBIdx:
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
#include <time.h>
using namespace std;
const int NUMBER_OF_A = 3E7;
const int NUMBER_OF_B = 7;
struct A {
long a, b, c, d, e, f;
string x, y, z;
};
struct B {
string id1;
vector<A> aVec;
};
struct A readA() {
A a;
a.a = 1;
a.b = 2;
return a;
}
int getBIdx(const A& a) {
return rand() % NUMBER_OF_B;
}
void Test1() {
vector<B> bVec;
for(int i = 0; i < NUMBER_OF_B; i++) {
B btmp;
bVec.push_back(btmp);
}
for(int i = 0; i < NUMBER_OF_A; ++i) {
A a = readA();
int idx = getBIdx(a);
bVec[idx].aVec.push_back(a);
}
}
void Test2() {
vector<A> vector;
for(int i = 0; i < NUMBER_OF_A; ++i) {
A a = readA();
int idx = getBIdx(a);
vector.push_back(a);
}
}
int main() {
time_t start = time(0);
Test1();
time_t end_of_test1 = time(0);
Test2();
time_t end_of_test2 = time(0);
cout << "Elapsed test 1:" << end_of_test1 - start << " s" << endl;
cout << "Elapsed test 2:" << end_of_test2 - end_of_test1 << " s" << endl;
return 0;
}
Result: (old Pentium 4 single core machine)
Elapsed test 1:17 s
Elapsed test 2:13 s
So it's slower but not that slower.
With -O3 the difference is even smaller:
Elapsed test 1:9 s
Elapsed test 2:7 s
I would try to optimize this code in two ways
define vector<A*> aVec instead of vector<A> aVec, to avoid copy constructor call ,since you are using C++0x
estimate the size of size of aVec in B, using resize() to resever some space might save some time
You should probably using the sizing constructor on bVec as it's size is known.
Then for the main culprit of filling it with vector of A, you probably
want to use vector::reserve on each avec inside bVec with an arbitrary size depending on your number of data to be fed.
Also, are you sure you compile with -O3 ?