Invalid deque <T> subscript . Why am I getting this error? - c++

I am getting the execption error in the following piece of code. Any suggestions on what might be causing it ?
Error : Invalid deque <T> subscript
typedef boost::shared_ptr<HistObj> shared_hist_def;
typedef std::deque<shared_hist_def> vector_def;
typedef boost::shared_ptr<vector_def> shared_vector_def;
typedef boost::unordered_map<int,shared_vector_def> in_map_def;
typedef boost::shared_ptr<in_map_def> shared_inner_map_def;
Domain::shared_hist_def& Domain::GetSpecificHistoricalTuple(const std::string& symb,const int& tframe,const int& val)
{
Domain::shared_inner_map_def tshare = stat_History_base[symb];
shared_vector_def tmp = tshare->at(tframe);
try
{
Domain::shared_hist_def safe_tuple = tmp->at(val);
return safe_tuple;
}
catch (std::exception &ex)
{
std::string a = ex.what();
__debugbreak();
}
}
More information:
The above method is a static method. And the program is multithreaded.Any chance that this error occurs because multiple threads access it. I had that assumption but then think that function parameters above could never be the same at one time.

Your val parameter seems to be too high (greater or equal to the number of elements in the deque), or maybe it's negative.

Related

Why is my out_of_range exception not being caught

I am new to cpp and I am trying out several things. This one I can't seem to figure out on my own.
#include <cstdio>
#include <stdexcept>
template <class E, class V>
struct Pair {
E first;
V second;
Pair(E fst, V snd) : first(fst), second(snd) {}
E getFirst() { return first; }
V getSecond() { return second; }
};
template <class t, unsigned dim>
struct vec {
t d[dim];
static constexpr int dimen = dim;
t &operator[](unsigned n) {
std::printf("dim: %d %d\n", dim, n);
if (n >= dim) {
std::printf("checking %d\n", n);
throw std::out_of_range("vector index is out of range");
}
return d[n];
};
};
int main() {
try {
Pair<int, vec<int, 2> *> test2(2, new vec<int, 2>{1, 2});
std::printf("%d\n", test2.getSecond()->dimen);
std::printf("before\n");
std::printf("%d\n", test2.getSecond()->d[2]); // it seems like the compiler kind of ignores this
} catch (std::out_of_range e) {
std::printf("Caught!!");
}
return 0;
}
Now, the line std::printf("%d\n", test2.getSecond()->d[2]); should ideally throw the out_of_range error, but it is not. My linter actually warns me that this is out of range also. I can compile and run the program and it returns some garbage 0 value.
My question is: why is either the error not being thrown or the error not being caught? I think the error is not being thrown because checking is not printed when I run it.
Because the throw code is never actually reached.
In this line here:
std::printf("%d\n", test2.getSecond()->d[2]);
getSection() returns a pointer to the vec object. When you then do ->d you are accessing the d array, within the vec object. Thus, when you add the [2] to the end, you are accessing the element at index 2 of the array, and are not calling operator[] of the vec object.
If you rewrite like this:
std::printf("%d\n", (*test2.getSecond())[2]);
Then the operator[] will be called on the vec object, and not its array. Note that you have to dereference the result of getSecond(). Alternatively, you can be more verbose:
std::printf("%d\n", test2.getSecond()->operator[](2));
Working example: https://godbolt.org/z/YWKzPz
Very good question!
The issue is that when you try to reference an item in an array via index, such as [2], you are actually referring to the size * 2 location. There is no built-in protection against it, but you can always check for \0 as that's where your arrays end. When you use arrays in C/C++, it is your job to make sure you are not outside of their location. It's generally a good idea to keep your array inside your structure/class and allow reaching its elements with setters and getters, which would handle the bounds and throw exceptions if those are violated.

Occasional segmentation fault in a struct operator function overload

I have a C++ structure defined as follows:
typedef struct event{
int id;
string name;
//int arg0;
QByteArray data;
bool operator<(const event& e) const
{
return id < e.id;
}
bool operator==(const event& e) const
{
return id == e.id;
}
}Event;
I also have a map defined as follows:
map<string, set<Event>> mapOfEventsByString;
When I want to see if an Event is associated to a given string I use this line of code:
if(mapOfEventsByString.find(aString)->second.count(event)==1)
{
//do stuff
}
Problem: Sometimes (and I mean that 9/10 times I can run the entire application with the exact same data set without any problems), I get a segmentation fault here:
bool operator<(const event& e) const
{
return id < e.id; <------- GIVES SEGMENTATION FAULT SOMETIMES
}
After many attempts at reproducing the error while debugging, I managed to pinpoint the segfault to that line. In that scenario e.id is filled with data and id says: "no such value".
Help?
Thank you
Without a backtrace we are only guessing, but this is a strong indication that the member id doesn't exist, so you're accessing memory you shouldn't.
If the member id doesn't exist, then your operator< call is broken. Given that it is invoked by the below highlighted part of your code:
if(mapOfEventsByString.find(aString)->second.count(event)==1)
// ^^^^^^^^^^^^^
that suggests to me that the below highlighted expression does not assuredly refer to a valid object:
if(mapOfEventsByString.find(aString)->second.count(event)==1)
// ^^^^^^
The only way that can happen is if the below highlighted dereference operation is invalid:
if(mapOfEventsByString.find(aString)->second.count(event)==1)
// ^^
which occurs when the find fails, returning mapOfEventsByString.end() (which cannot be dereferenced):
if(mapOfEventsByString.find(aString)->second.count(event)==1)
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
I think if you actually check for find success you'll see that, 1 out of 10 times, aString was not found in mapOfEventsByString.
Let's do this, instead:
const auto it = mapOfEventsByString.find(aString);
if (it != mapOfEventsByString.end() && it->second.count(event) == 1) {
// do stuff
}
Now you can put a breakpoint in for when it == mapOfEventsByString.end() and investigate why the find is failing. Good luck!

Vector in c++ error when trying to call at()

I'm trying to get a pointer to mytype of a vector(vector mytype*) but I get segmegation fault.
I've the following code:
void add(string b, vector<mytype*> *p){
int a;
mytype *fre=NULL;
a=oura.front();
oura.pop();
if(!(p->size()<a) && oura.size()>0){
fre=p->at(a-1); //Error seems to come from here
add(b,fre->get_vec());
}
else{ ...}
}
mytype was a class with a string and a vector<mytype*> pointer.
The error seems to come from fre=p->at(a-1)
oura is a queue<int> and takes values between 1-20 so i used (a-1).
at does bounds checking when accessing elements. If it's out of bounds it will throw an std::out_of_range exception.
adding an assert(a > 0); should let you find out when it happens.

Overloading [] in subclassed C++ string

What is the proper thing for me to return here?
char BCheckString::operator[](int index)
{
if (index < 0 || this->length() <= index)
{
throw IndexOutOfBounds();
???Do I need to return something here???
}
else
{
return ?????;
}
}
I tried return this[index] but VS2013 says: "no suitable conversion function from "BCheckString" to "char" exists. And I have no idea what to return after the throw.
I have:
class BCheckString : public string
{
private:
bool checkBounds();
public:
BCheckString(string initial_string);
char operator[](int index);
class IndexOutOfBounds{};
};
and
BCheckString::BCheckString(string initial_string) : string(initial_string)
{
}
char BCheckString::operator[](int index)
{
if (index < 0 || this->length() <= index)
{
//throw IndexOutOfBounds();
cout << "index out of bounds" << endl;
return 'A';
}
else
{
return 'A';
}
}
Obviously this is homework ;)
While observing that what you're doing here is unnecessary, the syntax is thus:
return string::operator[](index);
You're calling the operator[] of your string parent. This should be preferred to using c_str because string::operator[] does bounds checking in debug builds.
It's also worth noting that .at already does bounds checking in release builds, and throws std::out_of_range.
For the first question, no. After throwing an exception, you don't need to have a return statement. In fact, if you do, the compiler may warn you about "unreachable code".
First, deriving from std::string is not recommended: Why should one not derive from c++ std string class?
As to your questions:
1) After throw you don't return anything.
2) Your attempt to use operator[] is incorrect as you are not calling the parent class's std::string::operator[].
To call the correct operator[]:
else
{
return std::string::operator[](index);
}
this is a pointer, therefore this[index] will erroneously consider this as pointing to an array of instances to access the index-th of them. That will be an instance of the class itself and there's no implicit conversion from that to the declared return type char (this is what the error message is complaining about).
You need to get the char from the base string, and this is done with
return this->string::operator[](index);
If you derived from std::string you can just use c_str() method to access data.
return this->c_str()[index];

Recover from an vector out of reach error

is it possible to recover from vector "out of reach" error in C++?
Like this function:
vector<int> numbers;
bool isAccessable(int i)
{
try
{
numbers[i];
catch (...)
{
return false;
}
return true;
}
it's possible in C#, but c++?
If you just want to check whether the index is in range, then simply:
return i < numbers.size();
(You should also either compare with zero, or change the index to an unsigned type; size_t is the type usually used for array indexes.)
If you want to try to access the value, and throw an exception if the index is out of range, then use at rather than []:
try {
do_something_with(numbers.at(i));
return true;
} catch (std::out_of_range const &) {
return false;
}
In C++ there is no range check for operator[], but there is for vector::at().
Try
numbers.at(i);
instead.
Use std::vector::at() member function. It throws an out_of_range exception.