std::map mit operator>> Überladung füllen
-
Hi Leute,
ich versuche grade /proc/meminfo zu parsen und in einer std::map zu speichern.Das ganze klappt auch schon sehr gut allerdings bekomme ich immer Conditional jumps und uninitialised value of size 8 Fehler.(Ich denke die genauen Fehler muss ich nicht posten, wenn aber doch gewünscht mach ich das gerne) Debugging mache ich mit valgrind. Ich beschäftige mich seit gestern mit diesem Fehler und weiß nicht weiter. Aber zum Code:
std::istream& operator>>(std::istream& in, std::map<std::string, long>& my_map){ std::string tmp; long tmp2; in >> tmp >> tmp2; tmp.back() = '\0'; //überschreiben der ':' my_map[tmp] = tmp2; return in.ignore(std::numeric_limits<std::streamsize>::max(),'\n'); //damit kB nicht mitgenommen wird und ignoriert wird } bool RamInfo::ParseMemInfo(){ std::ifstream meminfo("/proc/meminfo"); if (!meminfo.is_open()) { return false; } for(;meminfo >> FullMemInfo;); //geht das schöner? Da wusste ich es nicht besser. :/ for (auto it = FullMemInfo.begin(); it != FullMemInfo.end(); ++it) { std::cerr << it->first << " " << it->second << '\n'; } return true; }Und hier mein privater Member:
private: std::map<std::string, long> FullMemInfo;Input:
MemTotal: 8169336 kB MemFree: 2155128 kB Buffers: 263032 kB Cached: 2290392 kB SwapCached: 0 kB Active: 3759544 kB Inactive: 1739936 kB Active(anon): 2947964 kB Inactive(anon): 41468 kB Active(file): 811580 kB Inactive(file): 1698468 kB Unevictable: 0 kB Mlocked: 0 kB SwapTotal: 0 kB SwapFree: 0 kB Dirty: 4360 kB Writeback: 0 kB AnonPages: 2946100 kB Mapped: 486200 kB Shmem: 43380 kB Slab: 268620 kB SReclaimable: 216832 kB SUnreclaim: 51788 kB KernelStack: 5736 kB PageTables: 62964 kB NFS_Unstable: 0 kB Bounce: 0 kB WritebackTmp: 0 kB CommitLimit: 4084668 kB Committed_AS: 7108248 kB VmallocTotal: 34359738367 kB VmallocUsed: 324688 kB VmallocChunk: 34359410300 kB HardwareCorrupted: 0 kB AnonHugePages: 0 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB DirectMap4k: 233024 kB DirectMap2M: 8146944 kBOutput(vor dem output kommen die Fehler d.h. es kommt vor der ausgaben Schleife die nur zum debuggen ist):
Active 3789916 Active(anon) 2976424 Active(file) 813492 AnonHugePages 0 AnonPages 2974616 Bounce 0 Buffers 264300 Cached 2294664 CommitLimit 4084668 Committed_AS 7193772 DirectMap2M 8146944 DirectMap4k 233024 Dirty 536 HardwareCorrupted 0 HugePages_Free 0 HugePages_Rsvd 0 HugePages_Surp 0 HugePages_Total 0 Hugepagesize 2048 Inactive 1743636 Inactive(anon) 44560 Inactive(file) 1699076 KernelStack 5720 Mapped 490884 MemFree 2120860 MemTotal 8169336 Mlocked 0 NFS_Unstable 0 PageTables 63004 SReclaimable 217136 SUnreclaim 51036 Shmem 46472 Slab 268172 SwapCached 0 SwapFree 0 SwapTotal 0 Unevictable 0 VmallocChunk 34359410300 VmallocTotal 34359738367 VmallocUsed 324688 Writeback 0 WritebackTmp 0
-
Da sind so spontan 2 Dinge, die mir auffallen.
Wenn "in >> tmp" fehl schlägt, dann ist tmp leer und "tmp.back()" liefert nichts sinnvolles.
Ausserdem ist der std::string kein null-Terminierter String. Er kann durchaus auch das Zeichen '\0' enthalten. Wenn Du das letzte Zeichen auf '\0' setzt, dann tust Du genau das. In C-Strings erwartet man, dass sich die länge des Strings um 1 verkürzt. Aber das ist nicht so bei std::string.
-
tntnet schrieb:
Da sind so spontan 2 Dinge, die mir auffallen.
Wenn "in >> tmp" fehl schlägt, dann ist tmp leer und "tmp.back()" liefert nichts sinnvolles.
Ausserdem ist der std::string kein null-Terminierter String. Er kann durchaus auch das Zeichen '\0' enthalten. Wenn Du das letzte Zeichen auf '\0' setzt, dann tust Du genau das. In C-Strings erwartet man, dass sich die länge des Strings um 1 verkürzt. Aber das ist nicht so bei std::string.
Danke für die Hinweise!
So besser:if (tmp.length() != 0) { tmp.erase(tmp.length()-1); } else { return in; }
-
Es klappt nach dem ich in der Zeile 16 folgendes geändert habe:
for(;meminfo >> FullMemInfo;){}Davor ist er immer zu weit gelaufen und damit in undefinierten bereich. Allerdings verstehe ich nicht ganz den Unterschied. Falls jemand ein paar Worte dazu sagen will immer gerne!

Ansonsten auch gerne Anregungen oder Verbesserungen erwünscht.
Danke!
-
Fuchs aus dem Wald schrieb:
So besser:
if (tmp.length() != 0) { tmp.erase(tmp.length()-1); } else { return in; }Sieht auf dem ersten Blick merkwürdig aus. Im Kontext ist das zwar dann richtig aber ich würde es nicht so formulieren. Es ist nicht leicht ersichtlich, dass es nach dem erase dann wieder nach dem if weiter geht.
Besser wäre:
if (tmp.empty()) return in; tmp.erase(tmp.length()-1);Das sieht man eher, was hier passiert. Und in C++11 gibt es auch ein "tmp.pop_back()".
-
Fuchs aus dem Wald schrieb:
Es klappt nach dem ich in der Zeile 16 folgendes geändert habe:
for(;meminfo >> FullMemInfo;){}Davor ist er immer zu weit gelaufen und damit in undefinierten bereich. Allerdings verstehe ich nicht ganz den Unterschied. Falls jemand ein paar Worte dazu sagen will immer gerne!

Ansonsten auch gerne Anregungen oder Verbesserungen erwünscht.
Danke!Das kann nicht das Problem gewesen sein. Ein {} ist hier das gleiche wie ein Semikolon. Aber auch hier nochmal der Hinweis, dass man das lesbarer gestalten kann. Der leere Schleifenrumpf ist sehr versteckt. Ich würde ihm auf jeden Fall in eine eigene Zeile spendieren. Und while geht hier auch:
while (meminfo >> FullMemInfo) ;
-
tntnet schrieb:
Besser wäre:
if (tmp.empty()) return in; tmp.erase(tmp.length()-1);Das sieht man eher, was hier passiert. Und in C++11 gibt es auch ein "tmp.pop_back()".
Ich muss sagen du hast recht, danke dafür! Allerdings will das tmp.pop_back nicht obwohl:
g++ -std=c++0xNaja klappt ja auch mit tmp.erase(...).
tntnet schrieb:
while (meminfo >> FullMemInfo) ;Auch das sehe ich ein.
Deswegen hab ich ja noch mal gefragt ob es schöner geht.
Würdest du das Semikolon wirklich in die nächste Zeile machen?
-
Auch das sehe ich ein. Deswegen hab ich ja noch mal gefragt ob es schöner geht.
Würdest du das Semikolon wirklich in die nächste Zeile machen?Definitiv ja! Dann sieht man sofort, was mit der Schleife gemeint ist. Wenn es am Ende der Zeile steht könnte es ein Flüchtigkeitsfehler gewesen sein.
-
Ok vielen danke an alle!