Can't iterate through std::map [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
Since I've started to using std::map I've started to receive assertion error whenever I click on the button. I want to clear all the contents inside my_map and start adding again everytime I click the button.
my.cpp
typedef std::map<str, MyClass> mapper;
mapper my_map;
void add_map(const str& name, MyClass* l) { /...../ }
void invoke_me()
{
Here I initialized variable i with the size of my_map, however, it returns the previous size before it was cleared
int i = my_map.size(); // i = 4, my_map.size() = 1
if (!my_map.empty())
{
for (const auto& it : map)
{
// Assert error: map/set iterator not incrementable
const MyClass& l = it.second;
l.on_clicked();
}
}
}
// cont'd
This should do the neat clearing of my_map, but I don't think it's doing the right job
void clear_map()
{
my_map.clear();
}
implementor.h
struct MyClass
{
std::function<void()> on_clicked;
};
implementor.cpp
MyClass button;
button.on_clicked = [&] {
clear_map();
add_map("MyButton", &button);
};
Well actually on_click is a callback, and it has to be called through the invoke_me function
main.cpp
while (RUNNING)
invoke_me();
I would say that it is because of incorrect map size that's why the it keeps looping even if it's out of bounds, or maybe I'd corrupted or messed up that map.

There might be more issues, but this looks to be the main one:
button.on_clicked = [&] {
clear_map();
add_map("MyButton", &button);
};
You're clearing the map, and this function gets called while you're iterating:
for (const auto& it : my_map)
{
// Assert error: map/set iterator not incrementable
const MyClass& l = it.second;
l.on_clicked();
}
Your iterators are being invalidated by the clear.

Related

I am facing an issue with pop while using C++ STL priority queue for my project [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
typedef std::priority_queue< Task*, std::vector< Task* > > Priority_Q;
class TaskQueue : public Priority_Q
{
public:
TaskQueue();
// Queue op
void push(Task* t){
Priority_Q::push(t);
}
void pop(){
Priority_Q::pop();
}
}
Is it the correct way to use priority_queue. I will be pushing objects derived from Task and popping it.
It should be easier to write a wrapper class and make STL priority_queue a member variable. But to make sure you set up the custom comparator for your queue, otherwise the STL data structure won't know how to order your objects. There are a couple of ways to do it. I'm just using one as example here.
If you want to add synchronization to your data structure, you can simple add internal locks and/or condition variables in your class to lock/unlock the member variable q.
class TaskQueue {
public:
TaskQueue() {};
bool empty() {
return q.empty()
}
void push(Task* t) {
q.push(t);
}
void pop() {
if (q.empty()) {
// You may want to do something here like throw an exception or not
}
// if not empty
q.pop();
}
Task* top() {
if (q.empty()) {
// You may want to do something here like throw an exception or not
}
return q.top();
}
private:
class TaskPtrComparator {
public:
bool operator()(Task* t1, Task* t2) {
// Comparison code here
}
};
priority_queue<Task*, vector<Task*>, TaskPtrComparator> q;
};

STL error: use of deleted function when sorting a vector of objects in C++ [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I have a view class with private vector of subviews
class MyView {
private:
const std::vector<MySubView> subViews_;
}
In the subview I have these methods:
class MySubView {
public:
const Id getId() const {
return id_;
}
const TimePoint getStartTime() const {
return startTime_;
}
private:
const Id id_;
const TimePoint startTime_;
}
Now in the one of the methods that constructor of MyView calls, I'm generating this array of subviews and set it, which works fine. The problem comes when I try to sort it before assigning.
static std::vector<MySubViews> buildLimitViews(
const ViewData& data);
When I try to sort the vector after building it in this method. I see errors. Sorting is the only part here that does not work.
std::vector<MySubView> buildLimitViews(
const ViewData& data) {
std::vector<MySubView> subViews;
//create views from data and push them in this vector, works fine.
// this sort block below does not work, causes errors.
std::sort(
subViews.begin(),
subViews.end(),
[](const MySubView& lhs,
const MySubView& rhs) {
if (lhs.getStartTime() == rhs.getStartTime()) {
return lhs.getId() < rhs.getId();
}
return lhs.getStartTime() < rhs.getStartTime();
});
return subViews;
}
If I comment out the sort block it works fine, otherwise I see this error:
error: use of deleted function 'MySubView&
MySubView::operator=(MySubView&&)'
Having const non-static member variables breaks assignment, because you cannot modify them. Make subViews_ non-const and it should work.

map<string, int> throws std::out_of_range when called from const function [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
Noticing a peculiar behavior when using std::map from a function that doesn't change the state of its object:
std::map<std::string, int> _attribLocations;
...
int ProgramInfo::getAttribLocation(const std::string& name) const
{
return _attribLocations.at(name);
}
When I call this function, passing a string literal, the lookup throws out_of_range exception:
auto index = info.getAttribLocation("v_position");
I noticed there are two versions of at(), one that uses a const_iterator, and one that doesn't:
mapped_type& at(const key_type& _Keyval)
{ // find element matching _Keyval
iterator _Where = _Mybase::lower_bound(_Keyval);
if (_Where == _Mybase::end()
|| _Mybase::_Getcomp()(_Keyval, _Mybase::_Key(_Where._Mynode())))
_Xout_of_range("invalid map<K, T> key");
return (_Where->second);
}
const mapped_type& at(const key_type& _Keyval) const
{ // find element matching _Keyval
const_iterator _Where = _Mybase::lower_bound(_Keyval);
if (_Where == _Mybase::end()
|| _Mybase::_Getcomp()(_Keyval, _Mybase::_Key(_Where._Mynode())))
_Xout_of_range("invalid map<K, T> key");
return (_Where->second);
}
};
It seems like the part that's causing it to throw is:
_Mybase::_Getcomp()(_Keyval, _Mybase::_Key(_Where._Mynode()))
I didn't really debug any deeper than this.
I'm using Visual Studio 2015.
I'm sure that the key being passed does exist in the map (from inspecting the map with a debugger). Could it be a bug in the map implementation, or maybe I'm missing something about comparing strings?
Ah, stupid mistake! It turns out the keys stored in my map were padded with terminating characters (they were thousands of characters long, mostly '\0'). I was passing in string literals like "gl_position", and the lookup was actually not finding anything. I was using [] operator in the non-const function, which returns the default int (0), which is the one I was expecting anyway. but at() failed to find the value, and threw. Here's what was happening:
class A
{
public:
A()
{
char* foo = (char*)malloc(40000);
foo[0] = 'f';
foo[1] = 'o';
foo[2] = 'o';
for (int i = 3; i < 40000; i++)
foo[i] = '\0';
std::string fooStr(foo, 40000);
map[fooStr] = 5;
}
int getAttribLocation(const std::string name)
{
return map[name];
}
private:
std::map<std::string, int> map;
};
int main()
{
A instance;
auto x = instance.getAttribLocation("foo");
return 0;
}
The confusion came from switching between [] and at(), because I couldn't use [] in a constant function.

What adress does "&ref_var" points to? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
Consider the following code:
std::vector &MyClass::getVector() const
{
return (myVec);
}
void aFunc()
{
std::vector *vec = &myClassInstance.getVector();
}
What adress does vec points to? Does it points to the very address of myVec in the myClassInstance object? (btw I know I should return a const ref, but it is an example).
You are returning a reference to myVec in the method getVector. When you take the address of a reference, you get the address of the variable the reference refers to. So vec will contain the address of myVec.
A reference is an alias to another variable. When you return a reference tomyVec from getVector() then you can consider calling the function to be exactly like accessing myVec if it were publicly available.
&MyClass.myVec == &myClassInstance.getVector()
What adress does vec points to?
The address of myClassInstance.getVector() will be the same as the address of myVec.
Also note that since you are returning an lvalue reference you can even use it on the left hand side of an assignment like
myClassInstance.getVector() = some_other_vector;
And now myVec will be a copy of some_other_vector.
Yes, it does point to the very vector myVec in your MyClass instance. See the following sample code:
#include <cstdio>
#include <vector>
class MyClass {
std::vector<int> myVec;
public:
MyClass() {}
~MyClass() {}
std::vector<int>& getVector()
{
return myVec;
}
void printVector() const
{
for(std::vector<int>::const_iterator it = myVec.begin(); it != myVec.end(); ++it)
{
printf("%d ", *it);
}
printf("\n");
}
};
int main(int, char**)
{
MyClass item;
std::vector<int>* vec = &(item.getVector());
vec->push_back(1);
item.printVector();
return 0;
}
Running this program will output:
$ ./a.out
1
So you can see that calling getVector() returns a reference to myVec from the MyClass instance, since we add a new item to the vector (vec->push_back(1)) via the vec pointer then print the MyClass instance's vector, and it shows that the item we added is there in myVec.

Vector erase iterator outside range [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
Porting some code from my game engine from Mac to Windows in C++, and I get this runtime error: "Vector erase outside range". It works on Mac!
void Entity::runDeferreds() {
for (auto it = deferreds.begin(); it != deferreds.end(); /* nothing */ ) {
if (it->Condition()) {
it->Execution();
it = deferreds.erase(it);
} else {
++it;
}
}
}
This iterates thru a list of "deferred" tasks, which are stored in a std::vector<DeferredCall> called deferreds. If the DeferredCall's Condition() is fulfilled, then its Execution() is run, and it should be removed from the vector. However, instead, I get the aforementioned error!
DeferredCall looks like this, not that it's too important:
struct DeferredCall {
std::function<bool()> Condition;
std::function<void()> Execution;
};
Help?!
EDIT:- Alternative Method
I also tried this, again working on Mac:
deferreds.erase(std::remove_if(deferreds.begin(), deferreds.end(),
[](DeferredCall &call) {
if (call.Condition()) {
call.Execution();
return true;
}
return false;
}
), deferreds.end());
However, in this case I get "vector iterators incompatible".
Although it doesn't answer where your error comes from, you may try to rework the code as follows:
const auto pred = [](Deferred& d){ return !d.Condition(); };
auto itMatch = std::partition( defs.begin(), defs.end(), pred);
const auto action = [](Deferred& d){ d.Execution(); };
std::for_each(itMatch, defs.end(), action);
defs.erase(itMatch, defs.end());
Also, std::vector::erase is guaranteed to return perfectly valid iterator. Could be vector::end() though.
Links: std::partition, std::for_each, std::vector::erase