Mam sobie klasę, która jest singletonem:
//plik h:
#ifndef _MAC_ADDRESS_H
#define _MAC_ADDRESS_H
#include "popenrr.h"
#include <iostream>
#include <map>
class MACAddress
{
private:
static MACAddress *instance;
std::map<std::string, std::string> mapOfMACs;
protected:
MACAddress() ;
virtual ~MACAddress(){};
inline std::string getStringIfconfig()
{
return POpenRR::getResultOfPopen("ifconfig -a | grep HWaddr") ;
}
public:
static MACAddress *Instance() ;
static void Release() ;
void RefreshMapOfMACs() ;
std::string GetMAC(std::string interface) ;
};
#endif
//plik.cpp:
#include "macaddress.h"
#include <utility>
MACAddress *MACAddress::instance = NULL;
MACAddress::MACAddress()
{
}
MACAddress *MACAddress::Instance()
{
if(!instance)
{
instance = new MACAddress ;
}
return instance;
}
void MACAddress::Release()
{
if(instance)
{
delete instance;
instance = NULL ;
}
}
void MACAddress::RefreshMapOfMACs()
{
std::string ifconfig = getStringIfconfig() ;
std::string interface ;
std::string MAC ;
mapOfMACs.clear() ;
std::istringstream iss(ifconfig) ;
std::string tempString;
int i=0;
while(iss>>tempString)
{
switch(i)
{
case 0:
{
interface=tempString;
}break;
case 4:
{
MAC=tempString;
std::cout<<interface<<" : "<<MAC<<"\n";
mapOfMACs[interface] = MAC ;
}break;
default:
{
}
}
i++;
i%=5;
}
}
std::string MACAddress::GetMAC(std::string interface)
{
std::cout<<"rozm = "<<(mapOfMACs.size())<<"\n";
if(mapOfMACs.empty())
{
RefreshMapOfMACs();
}
return mapOfMACs[interface] ;
}
O co chodzi? Ano o to, że coś dziwnego dzieje się z mapą
std::map<std::string, std::string> mapOfMACs;
. Nigdy nie jest empty(), próba sprawdzenia jej rozmiaru daje za każdym razem inne dziwne rezultaty: rozm = 3075230046
Można tylko raz na niej wywołać clear(). Każde dodatkowe clear() jak również każda próba dostania się do jej elementów lub jej zmiana zawartości powoduje segfault.
Przykładowe wykorzystanie tej klasy:
MACAddress::Instance()->GetMAC("eth0");
Gdy pozmieniam funkcję GetMAC() tak, aby nie sprawdzała rozmiaru mapy, tylko za każdym razem robiła RefreshMapOfMACs wywala mi na pierwszej próbie zapisu do mapy:
rozm = 3075230046
eth0 : 00:1b:fc:dc:14:7f
Naruszenie ochrony pamięci
Kod pisany po nocach, to nie jest dobry pomysł. Kto mi powie, co jest źle z tą mapą?