Strange behaviour with std::vector - c++

consider this segment of codes:
std::vector<int> vecList;
...populate 3 elements into vecList...
if (!vecList.empty())
{
std::cout << "List count = " << vecList.size() << std::endl;
if (vecList.empty())
{
std::cout << "List is empty" << std::endl;
}
}
my printout is:
List count = 3
List is empty
I did not do anything to "vecList" other than printing out, yet after I printed the size of the vector, the size becomes 0. How is that possible? Any advice is appreciated.
This happened when I am running my build on an Iphone environment.
Thanks
Alexander

Since both std::vector<>empty() and std::vector<>::size() are const member functions and cannot alter the vector's content, the only ways I can see to get that result is by using multiple threads or invoking Undefined Behavior.
Likely candidates are other threads modifying the vector and messing up the vector's internals by buffer overflows and the like.
This
#include <iostream>
#include <vector>
int main ()
{
std::vector<int> vecList;
vecList.push_back(1);
vecList.push_back(2);
vecList.push_back(3);
if (!vecList.empty())
{
std::cout << "List count = " << vecList.size() << std::endl;
if (vecList.empty())
{
std::cout << "List is empty" << std::endl;
}
}
return 0;
}
prints List count = 3 for me. I bet it does the same for you. If so, then there must be something messing things up in the code you don't show.
The only way to find out what it is (other than posting the exact right snippet here and have someone guess right) is to remove all extra code step by step until the problem disappears and then look at the code that triggered it.

You might also want to try Valgrind. Allot of times use of uninitialized values, especially with system calls can cause truly weird behavior.
For instance, a common mistake is the following ( yeah I've made this mistake myself ):
struct timeval tv;
tv.tv_sec = 5;
// This is supposed to sleep for 5 seconds
select(0, NULL,NULL,NULL, &tv);
What's missing? You need to init the second member of the struct as such tv.tv_usec = 0; otherwise it can cause seemingly random errors in completely unrelated sections of the program. Valgrind can help you catch some of these things.

Try debuging your code. It is easy and you will understand when exactly it becomes empty. Though, there is nothing ideal, anyway trust such constructs like STL and other well-kown libraries. In 99.99% cases the cause of the promblem is the programmer.

Looks your code like this? Note the semicolon after the second if.
std::vector<int> vecList;
...populate 3 elements into vecList...
if (!vecList.empty())
{
std::cout << "List count = " << vecList.size() << std::endl;
if (vecList.empty());
{
std::cout << "List is empty" << std::endl;
}
}

If this actually happens, it's most probably another thread modifying the vector.

Related

Access vector elements *strictly inside* the allocation with subscript, after reserve() [duplicate]

This question already has an answer here:
reserve() - data() trick on empty vector - is it correct?
(1 answer)
Closed 2 years ago.
I have seen these questions:
Weirdness of the reserve() of vector
Is accessing the raw pointer after std::vector::reserve safe?
How reserve in std::vector works + Accessing vector with []
And a few others. But all of them deal with accessing the elements outside of the reserved space. I am interested in those strictly inside.
For example:
#include <iostream>
#include <vector>
int main()
{
std::vector<int> a;
a.reserve(3);
a[0] = 4;
std::cout << a[0] << ',' << a[1] << ',' << a[2] << '\n';
std::cout << *(a.data()) << '`' << *(a.data() + 1) << '`' << *(a.data() + 2) << '\n';
a[2] = 7;
for(int &i: a)
std::cout << i << ',';
std::cout << '\n';
std::cout << a[0] << ',' << a[1] << ',' << a[2] << '\n';
std::cout << *(a.data()) << '`' << *(a.data() + 1) << '`' << *(a.data() + 2) << '\n';
return 0;
}
This prints:
4,0,0
4`0`0
4,0,7
4`0`7
The empty line is the output of the for, and it makes sense: I only reserved memory, the vector considers there is no data.
I've been playing with this for an hour already, always staying within the confined space, and it never once crashed. I added -fsanitize=address -Wall -Wpedantic, no complaints (also on SO, but I lost the link). Also notice that I am directly dereferencing the data(), and it seems to be fine with it. So I have to wonder, is this undefined behavior?
I suppose the code above will make some cringe (I can't tell), but prettiness is not my goal with this -- it's just a personal goal.
To be more specific, I was trying to convert a Fortran eigenvalue program, but I know maybe two things in Fortran, rounded up, and while switching back and forth between the browser and the compiler, I stumbled across std::vector reserve() and push_back() is faster than resize() and array index, why? and a few similar others. And, sure enough, it works, but when I tried to use [] instead of push_back(), or insert(), it went even faster, a lot faster. I know this is a bit of a premature optimization, but I'd rather put out the fire now, while it's hot, rather than later.
So, here I am.
Your program has undefined behavior because it reads uninitialized memory. reserve reserves the space but does not initialize it.

std vector does not throw out_of_range exception when accessing uninitialized elements [duplicate]

This question already has answers here:
Vector going out of bounds without giving error
(4 answers)
Closed 5 years ago.
I read this tutorial
std::vector beginners tutorial
and also saw this question:
similar tpoic question
Yet, when I run my simple example I did not see the excepted results, which are --> an std::out_of_range exception is NOT thrown.
Did I misunderstand here something ?
The sample code I run is the following (the code run and terminates successfully, i.e.- no exceptions thrown):
#include <iostream>
#include <vector>
using namespace std;
class MyObjNoDefualtCtor
{
public:
MyObjNoDefualtCtor(int a) : m_a(a)
{
cout << "MyObjNoDefualtCtor::MyObjNoDefualtCtor - setting m_a to:" << m_a << endl;
}
MyObjNoDefualtCtor(const MyObjNoDefualtCtor& other) : m_a(other.m_a)
{
cout << "MyObjNoDefualtCtor::copy_ctor - setting m_a to:" << m_a << endl;
}
~MyObjNoDefualtCtor()
{
cout << "MyObjNoDefualtCtor::~MyObjNoDefualtCtor - address is" << this << endl;
}
// just to be sure - explicitly disable the defualt ctor
MyObjNoDefualtCtor() = delete;
int m_a;
};
int main(int argc, char** argv)
{
// create a vector and reserve 10 int's for it
// NOTE: no insertion (of any type) has been made into the vector.
vector<int> vec1;
vec1.reserve(10);
// try to access the first element - due to the fact that I did not inserted NOT even a single
// element to the vector, I would except here an exception to be thrown.
size_t index = 0;
cout << "vec1[" << index << "]:" << vec1[index] << endl;
// now try to access the last element - here as well: due to the fact that I did not inserted NOT even a single
// element to the vector, I would excpet here an excpetion to be thrown.
index = 9;
cout << "vec1[" << index << "]:" << vec1[index] << endl;
// same thing goes for user defined type (MyObjNoDefualtCtor) as well
vector<MyObjNoDefualtCtor> vec2;
vec2.reserve(10);
// try to access the first element - due to the fact that I did not inserted NOT even a single
// element to the vector, I would except here an exception to be thrown.
index = 0;
cout << "vec2[" << index << "]:" << vec2[index].m_a << endl;
// now try to access the last element - here as well: due to the fact that I did not inserted NOT even a single
// element to the vector, I would except here an exception to be thrown.
index = 9;
cout << "vec2[" << index << "]:" << vec2[index].m_a << endl;
return 0;
}
Notes:
The sample code is compiled with -std=c++11 option.
Compiler version is g++ 5.4 (on my Ubuntu 16.04 machine).
Thanks,
Guy.
A vectors operator[] function may or may not do bounds-checking. The implementations that do have bounds-checking, typically only does it for debug-builds. GCC and its standard library doesn't.
The at function on the other hand, does have mandatory bounds-checking and will be guaranteed to throw an out_of_range exception.
What happens here is simply that you go out of bounds and have undefined behavior.
Is at() that perform the range check, not (necessarily) operator[].
Your code have udefinded behaviour.
If you want to be sure to get an exception, use
vec1.at(index)
instead of
vec1[index]

Allocating Dynamic Memory to PlayerID

For hours now I've been trying to work out to how I can assign dynamic memory to a certain playerid, when they join a server, and destroy it when they leave.
I've tried numerous things, I've tried making an array of pointers... which would allow me to access the information with the player ID using the pointer and array position:
int *pInfo[MAX_PLAYERS]; // Global
//Function Local
CPlayers p;
pInfo[playerid] = p;
Which doesn't work, it tells me it cannot convert the class initialisation to a memory pointer.
I tried the same thing, with this line instead:
std::unique_ptr<CPlayers> pInfo[playerid];
However it needs a constant expression where playerid is, this means I cannot do this unless I know what the player ID is and enter it directly... which is impossible as I won't know until they client tries to connect.
Does anyone have a solution that will allow me to make memory dynamically, and have this memory accessible via the playerid. Or some other fashion, that me indefinitely use that clients information in game.
As I have ran out of ideas... I can't find anything online. I'm new as well so there may be functions I've over looked.
Thanks.
You can use MAP container to do that. The ideia is that you have 2 values. The first one is the playerID and the second one, a dynamic memory reference, which contains its properties. Following is a simple example to prove the concept.
#include <map>
#include <memory>
#include <iostream>
int main()
{
std::map<int, std::unique_ptr<int>> pinfo;
// Inserting some elements.
pinfo.emplace(1, std::unique_ptr<int>(new int{3}));
pinfo.emplace(800, std::unique_ptr<int>(new int{700}));
for (auto& i: pinfo)
std::cout << "Player " << i.first << ", value " << *i.second.get() << std::endl;
// Deleting. Note that, due unique_ptr, the memory is deallocated automatically
pinfo.erase(1);
std::cout << "Player 1: deleted" << std::endl;
for (auto& i: pinfo)
std::cout << "Player " << i.first << ", value " << *i.second.get() << std::endl;
}

Access Violation Reading Location using open file stream

I know that this question has been asked lots of times. But, in my case, the error is not always present so I think it might be different. I am using C++, Visual Studio 2013, Windows 7 x64.
Here's the relevant code:
void writeDATAToFile(const char *fname, string title, const VecDoub& spec_x, const VecDoub& spec_y, const VecDoub& freq)
{
ofstream of;
of.open(fname, ios_base::out);
if (!of.is_open())
{
return;
}
of << "somename" << endl;
of << "WAVES/S" << "\t" << title << endl;
of << "BEGIN" << endl;
for (int i=0; i<spec_x.size(); i++)
{
of << spec_x[i] << "\t\t\t" << spec_y[i] << "\t\t\t" << freq[i]<<endl;
}
of << "END" << endl;
of.close();
}
This function is supposed to write the spectrum data (calculated earlier in the program) and write it to a file. Some spectrum data won't cause a problem, some will. The error is in the for loop.
Here is the error window:
You're passing 3 vectors to your function:
const VecDoub& spec_x, const VecDoub& spec_y, const VecDoub& freq
but you never check that they have the same size.
In your loop (not the "second" loop as you said in your question, there's just one loop in the code you posted), you're iterating over spec_x and you use the same index i to index into the other two vectors.
What if one or both of your other two vectors have a smaller size than spec_x? Then you're indexing out of bounds which would cause the error you're seeing.
The error message clearly says it is trying to read something it shouldn't be.
You code loops thus:
for (int i=0; i<spec_x.size(); i++)
{
of << spec_x[i] << "\t\t\t" << spec_y[i] << "\t\t\t" << freq[i]<<endl;
}
This assumes spec_x, spec_y and freq are the same size.
You could check this before looping and throw an error if this
precondition doesn't hold.
You could loop up to the smallest size of all three.
You could leave this function as is and put checks where you populate the data originally.
Note - the debugger is trying to help you. If you hit "break" it will five you a call stack, and then you should be able to see exactly which variable is causing the problem.

std::cout prevents a segfault in function?

I'm using the finite element library for some calculations, and I've encountered a bizarre problem.
I basically have the following for loop:
MeshBase::const_node_iterator node_it = mesh.nodes_begin();
for (unsigned int i=0;i<n_nodes;i++ , node_it++){
const Node* node2 = *node_it;
Point dumpoint( (*node2)(0), (*node2)(1), (*node2)(2));
Number dumreal= (Number) mesh_data.get_data(node2)[0];
// std::cout << dumreal <<std::endl;
dummap[dumpoint] = mesh_data.get_data(node2)[0];
}
If I uncomment the line with cout, it works. Otherwise I get a segfault. It doesn't matter what I print:
std::cout << std::endl;
An important note is that dummap is a global
std::map<Point,Number>
Using valgrind showed that the problem was with some char* array I allocated somewhere else.
Thanks ^^