I'm experiencing a weird behavior in a range based for
loop over a map
in C++ under Ubuntu 18.04
(with or without VisualStudio) and I've tried many rewrites unsuccessfully. Everything I found here and in the rest of the WWW just showed conceptual basics of the range based loop or trivial mistakes.
This is a VisualStudio C++ Linux project, whose language standard is set to C11, C++11 (-std=c11
, -std=c++11
). There are also GNU variants (-std=gnu11
and -std=gnu++11
) and I even tried C++17, however they didn't make any difference.
Basically, I have the following classes: a transmission handler called MyTransmitter
, a data cache called MyCache
and a data object called MyData
. The following code shows the definition of a method that iterates over the data objects in order to transmit and mark them as sent:
void MyTransmitter::Transmit()
{
map<const string, MyData> alldata = this->Cache.CurrentData;
for (pair<const string, MyData> kvp : alldata)
{
Data data = kvp.second;
// do stuff
kvp.second.IsTransferred = true;
}
}
Problem: After rewriting my initial naive attempt to a range based loop the program stopped transmitting anything and so I started debugging in VisualStudio 2017 (I didn't see any error, btw.). I was able to reproduce that the first line is executed, but when I try to run the next command (which is the for loop), the execution focus jumps immediately to the end of the method. With a breakpoint at the start of the method I saw that the alldata
variable has been assigned something, but I only see alldata {...}
when I hover over it. The Cache
part allowed me to see a bit more, when I hovered over it and I could navigate via CurrentData
to nothing more but a message like subordinate elements could not be evaluated
(or something along those lines, German version).
For clarity I add the shortened class headers here:
MyTransmitter.h
:
#include <iostream>
#include "MyCache.h"
#include <cstdlib>
#include <iomanip>
#include <map>
using namespace std;
class MyTransmitter
{
public:
MyTransmitter(MyCache cache, const string x, const string y);
~MyTransmitter();
void Transmit();
private:
MyCache Cache;
string X;
string Y;
}
MyCache.h
:
#include <regex>
#include <string>
#include "MyData.h"
#include <map>
using namespace std;
class MyCache
{
public:
MyCache();
~MyCache();
void Register(string key, bool z);
void Deregister(string key);
void Change(string key, double value);
map<const string, MyData> CurrentData;
}
MyData.h
:
#include <string>
#include <chrono>
#include <cmath>
using namespace std;
typedef chrono::high_resolution_clock MyClock;
typedef chrono::nanoseconds MyTimeSpan;
typedef chrono::time_point<chrono::system_clock, MyTimeSpan> MyTimePoint;
class MyData
{
public:
MyData();
~MyData();
bool IsTransferred;
bool Z;
string Key;
double PreviousValue;
double CurrentValue;
MyTimePoint PrevousTimeStamp;
MyTimePoint CurrentTimeStamp;
}
To invoke the problematic piece, the main()
method looks like:
#include <cstdio>
#include <cstdlib>
#include <regex>
#include <string>
#include <iostream>
#include <unistd.h>
#include <time.h>
#include <chrono>
#include <hash_map> // I also tried <map>
#include "MyTransmitter.h"
int main()
{
MyCache mc;
MyTransmitter mt(mc, "bla", "blabla");
InitMyData(); // this populates the cache via mc.Register() and definitely works
// do some stuff here executing something like mc.Change("somekey", 1234.5) - also definitely working
mt.Transmit(); // here, the problematic method is called and returns immediately
return 0;
}
At the end of InitMyData()
the cache is definitely populated correctly and the changes afterwards are OK, too, but it seems strange to me that I can't see anything later in the Transmit()
method while debugging.
Question: What am I doing wrong here and how can I fix it? Is memory management playing tricks with me or am I missing some pointer stuff here or are there any silently failing ambiguities regarding the map
type that I am not aware of? Is this a sign of a wrong C++ language standard?
Aucun commentaire:
Enregistrer un commentaire