Operator += applied to std::valarray<int*> - c++

Here is the example:
#include <iostream>
#include <string>
#include <valarray>
int main()
{
std::valarray<std::string> vs(2);
// vs[0] += "hello"; // works
// vs[1] += "hello"; // works
vs += "hello"; // works
std::cout << vs[0] << std::endl;
std::cout << vs[1] << std::endl;
std::valarray<int*> vi(2);
vi[0] = new int[2];
vi[0][0] = 0;
vi[0][1] = 1;
vi[1] = new int[2];
vi[1][0] = 2;
vi[1][1] = 3;
std::cout << vi[0][0] << std::endl;
std::cout << vi[1][0] << std::endl;
// vi[0] += 1; // works
// vi[1] += 1; // works
vi += 1; // error: invalid operands of types 'int*' and 'int*' to binary 'operator+'
std::cout << vi[0][0] << std::endl;
std::cout << vi[1][0] << std::endl;
}
I don't understand this error, if someone may explain this to me.
Is there a workaround?
Best regards,

std::valarray doesn't have overloads for heterogeneous binary operations, but it does have a catch-all for other functions, apply.
vi.apply([](int * p){ return p + 1; });

You can see operator+ overloads for valarray here. As you can see no overload is suitable for what you're trying to do (add an int and a pointer).

My last dabble in C++ has been a while, so please excuse any slipups in terms of terminology/details.
What your error boils down to is that += on a valarray attempts to perform the operation on each element of the valarray. And by default (if my memory doesn't deceive me), there's no + operation for integer pointers, which are stored in your valarray. You'd need to specify an overridden + operator for int pointers first.
Also, for an explanation of why the other operations work and vi += 1 doesn't:
vi[0] += 1; // works
vi[1] += 1; // works
These work, because (and I don't know if that's what you intended to do) you've placed integers in these vararray fields (new int(n) will create an int with a value of n), each with a value of 2. So vi[0] is 2, as is vi[0]. You could as well have written
vi[0] = 2;
vi[1] = 2;
I'm assuming you were trying to instead have an integer array stored in vi[0]/vi[1], which would've been
vi[0] = new int[2];
vi[1] = new int[2];
The problem is that per documentation, vi[0][0] = 0, etc... simply prompt the valarray to create these fields if they don't exist already, so of course
std::cout << vi[0][0] << std::endl;
std::cout << vi[1][0] << std::endl;
will work.

Related

How can I make a vector with all the video modes in SFML?

I have this:
std::vector <sf::VideoMode> *screenResolution = new std::vector<sf::VideoMode>;
*screenResolution = sf::VideoMode::getFullscreenModes();
for (std::size_t i = 0; i < screenResolution->size(); ++i)
{
std::cout << screenResolution[i]->width << ":" << screenResolution[i]->height <<std::endl;
}
And for some reason an error appears in the cout that says "the expresion must be a type of pointer".
You have to carefuly read error message. Your vector is of sf::VideoMode which doesn't look like pointer. Only -> can dereference pointers, so you can't use it in your loop. You also probably don't need dynamic allocation for your vector.
The following code should work for you:
std::vector<sf::VideoMode> screenResolution = sf::VideoMode::getFullscreenModes();
for (std::size_t i = 0; i < screenResolution.size(); ++i)
{
std::cout << screenResolution[i].width << ":" << screenResolution[i].height << std::endl;
}

Array of int or vector?

i'm trying to store some elements that is going to change every time, but i don't know which
way is better and why. I'm thinking about two ways, 1) declaring array of int and loop or
use vector's.
Which way is better and why?
Does declaring array of int have any future memore problems as leak?
the code down below show the two ways i'm talking about:
1)
#include <iostream>
#include <vector>
int main()
{
int x[5];
x[0] = 10;
x[1] = 20;
x[2] = 30;
x[3] = 40;
x[4] = 50;
for(unsigned int i = 0;i<=sizeof(x[5]); i++)
{
std:: cout << "x[" << i << "] = "<< x[i] << std::endl;
}
system("pause");
return 0;
}
2)
#include <iostream>
#include <vector>
int main()
{
std::vector<int> x;
x.push_back(10);
x.push_back(20);
x.push_back(30);
x.push_back(40);
x.push_back(50);
for(unsigned int i = 0;i<=x.size()-1; i++)
{
std:: cout << "x[" << i << "] = "<< x[i] << std::endl;
}
system("pause");
return 0;
}
If this is all you have to do, and your array will always have a size that is known at compile time, then you do not need std::vector.
On the other hand, in C++11 you could use std::array instead of a plain C array (std::array is a zero-overhead, safer and more functional wrapper over a C array):
#include <iostream>
#include <array>
int main()
{
std::array<int, 5> x = { 10, 20, 30, 40, 50 };
for (unsigned int i = 0; i < x.size(); i++)
// ^^^^^^^^
{
std:: cout << "x[" << i << "] = "<< x[i] << std::endl;
}
}
Here is a live example. Notice, that std::array offers a size() member function which you may want to use instead of the sizeof operator.
Moreover, since std::array is a standard sequence container, you could iterate through its element this way:
std::size_t i = 0;
for (auto e : x)
{
std:: cout << "x[" << i++ << "] = "<< e << std::endl;
}
Here is a live example.
If the size is known at compile time, use std::array. If not, use std::vector. In either case, use iterators to look at the elements:
typedef std::array<int> my_container_type;
typedef my_container::iterator iterator;
my_container_type my_container = { whatever };
for (iterator it = my_container.begin(); it != my_container.end(); ++it)
std::cout << "x[" << (it - my_container.begin()) << "] = " << *it << '\n';
By using iterators you greatly reduce the risk of accidentally using a loop limit like sizeof(x[5]), which is nonsense.
Neither is "better". They both address entirely different use cases.
If you know the array size at compile time and are 100% sure it will never change, sure, use a plain old array. It has less overhead, and the compiler can even aid you with static analysis by spotting any attempts to read outside the boundaries.
On the other hand, if you are unsure of the array's side (i.e. you will be reading input from a file or the user), then use the std::vector. It can grow to any size to meet your needs.

Operator Overloading = Negation not working as intended

So I'm working with operator overloading and just realized that my negation operator isn't working as it should be. I'm not exactly sure what I've done wrong.
The .h signature
Vector & Vector::operator-()
The .cpp implementation
Vector & Vector::operator-()
{
pVec[0] = -pVec[0];
pVec[1] = -pVec[1];
pVec[2] = -pVec[2];
return *this;
};
Calling:
cout << "-Vector E = " << -VecE << (-VecE).Magnitude() << endl << endl;
The variables in VecE are like [0, 1 , 1] which means when this is called it should display them as [0, -1, -1] but it's not. So what am I missing?
EDIT: Adding copy constructor and iostream<< overload code:
Vector::Vector(const Vector & Copy)
{
pVec = new double[3];
if (0 == pVec)
{
exit(1);
}
else
{
pVec[0] = Copy.pVec[0];
pVec[1] = Copy.pVec[1];
pVec[2] = Copy.pVec[2];
}
};
ostream & operator<<(ostream & Out, Vector & RHS)
{
cout.precision(1);
Out << fixed << "[ " << RHS.pVec[0] << " " << RHS.pVec[1] << " " << RHS.pVec[2] << " ]" << resetiosflags (ios_base::fixed);
return Out;
};
You need to return a copy of the vector. The way this is written, the expression -VecE will actually modify VecE! Since you evaluate -VecE twice, you are negating the vector twice, and (of course) the negation of the negation is the original value.
To implement this change, you need to alter the operator-() declaration to return a Vector instead of a Vector &.
For example:
Vector Vector::operator-()
{
Vector copy(*this);
copy.pVec[0] = -copy.pVec[0];
copy.pVec[1] = -copy.pVec[1];
copy.pVec[2] = -copy.pVec[2];
return copy;
};
cdhowie is right. You are negating twice.
That said, I don't think you need to change the implementation.
Vector const NegVecE = -VecE;
cout << "-Vector E = " << NegVecE << NegVecE.Magnitude() << endl << endl;
EDIT: As PiotrNycz notes, though this will work, the end state is un-intuitive and therefore the correct solution is to return a copy.
{
int i = 3;
int j = -i; //you would expect i to still be 3 here
}

CPP: Mysterious error for array initialization and crash?

My program seems to always produce ridiculous errors.
Please provide directions for me. The following code segment cutout all irrelevant parts.
Thanks.
Part A of the code segment seems failed to initialize the array correctly, how to debug?
Part B of the code segment always crash, is there anything i missed?
typedef unsigned long T_PSIZE;
int main()
{
int AG_TOTAL = 6 ;
/* part A1 */
T_PSIZE* cntPeopleByAge = new T_PSIZE[AG_TOTAL + 1];
/* part A2 - originally i use static array like this, but it also fails */
//T_PSIZE cntPeopleByAge T_PSIZE[AG_TOTAL + 1];
for (int i = 0; i < (AG_TOTAL + 1); i++)
{
std::cout << i << ":" << cntPeopleByAge[i] << "\t";
cntPeopleByAge[i] = 0;
std::cout << cntPeopleByAge[i] << "\n";
}
std::cout << "cntPeopleByAge:" << cntPeopleByAge[ AG_TOTAL + 1 ] << "\n";
/* part B */
delete [] cntPeopleByAge;
return 0; // <--- crash here!
}
Sample Output
0:200320 0
1:201581 0
2:201582 0
3:201583 0
4:0 0
5:0 0
cntPeopleByAge:1799119387:0:0
Platform: win 7 x64
Compiler: TDM-GCC x64
for (int i = 0; i < (AG_TOTAL + 1); i++)
{
std::cout << i << ":" << cntPeopleByAge[i] << "\t";
// ^^^^^^^^^^^^^^^^
// You're reading uninitialized memory here
cntPeopleByAge[i] = 0;
std::cout << cntPeopleByAge[i] << "\n";
}
And here
std::cout << "cntPeopleByAge:" << cntPeopleByAge[ AG_TOTAL + 1 ] << "\n";
you're going out of bounds. The last valid index is AG_TOTAL.
You've got undefined behaviour (UB). The errors are only as ridiculous as UB can be.
/* Sorry. but that earlier answer is not correct. The loop correctly starts at zero and ends at < the limit. The problem is that you are declaring an array of pointers, but never allocating memory to the objects that they point to. Your output is showing you addresses not numbers. One way is to allocate the objects as you use them (you must delete them individually as well) */
T_PSIZE* cntPeopleByAge = new T_PSIZE[AG_TOTAL + 1];
for (int i = 0; i < (AG_TOTAL + 1); i++)
{
cntPeopleByAge[i] = new T_PSIZE();
}
What you really want to use is the vector class in the standard library which handles all of this for you:
#include <vector>
std:vector<T_PSIZE *> cntPeopleByAge;
cntPeopleByAgex.resize(AG_TOTAL + 1);
Good luck ...

Dereferencing pointers to members of union

The following code prints '2' four times. Why does it never print '1'? Can someone explain me exactly what is happening here?
#include <iostream>
int main () {
union IntegersUnion {
int a;
int b;
};
IntegersUnion q;
q.a = 1;
q.b = 2;
std::cout << "(*(&q.a)) = " << (*(&q.a)) << std::endl;
std::cout << "(*(&q.b)) = " << (*(&q.b)) << std::endl;
std::cout << "(*(&(q.a))) = " << (*(&(q.a))) << std::endl;
std::cout << "(*(&(q.b))) = " << (*(&(q.b))) << std::endl;
return 0;
}
A union shares the memory between its members. By doing:
q.a = 1;
q.b = 2;
the second assignment overwrites the a.
union uses the same memory for all of its members.
So, when you assign q.b = 2;, q.a will be 2, too.
Every item in the union refers to the same location.
The most common use of union is something like this:
struct {
int dataTypeID;
union {
char char_here;
int number_here;
}
} incoming_data;
In this example, incoming_data is data imported from a file, where dataTypeID tells you what kind of data it is. (There are many file formats which optimize space in this fashion.)