Ostrożnie z konstruktorem std::string

Niesłychanie użyteczna klasa std::string zawiera pułapkę. Wystarczy wykonać jakiś wariant polecenia

   string s = (char *) 0;

a wiele implementacji standardowej biblioteki C++ spróbuje zaglądać do komórki pamięci o adresie 0.

Dwa-trzy lata temu gwałt pamięci następował w niemal wszystkich znanych mi implementacjach, ostatnio sytuacja się poprawia ale problem ciągle jest spotykany.

Problem jest poważniejszy niż się na pierwszy rzut oka wydaje: kodu takiego, jak powyższy raczej nikt nie napisze ale fragment taki jak poniżej:

    string s = some_fun();

jest często spotykany a łatwo też pomylić kolejność parametrów czy zapomnieć o ciapkach i uzyskać coś w stylu

    void some_fun(const string& a, const string& b, int c);
    ...
    some_fun("Mam", 0, 7);

Drugi z powyższych przypadków wyjdzie na jaw szybko. Ale w pierwszym, wystarczy, by some_fun() (będące np. funkcją z jakiejś zewnętrznej biblioteki) zwracało char * lub const char * i w niesłychanie rzadkich okolicznościach zdarzało się jej zwrócić zero jako sygnał błędu i nieszczęście gotowe.

Kilka lat temu straciłem sporo czasu poszukując przyczyny tajemniczych awarii od dawna wdrożonej i działającej bez problemów aplikacji. Jak się w końcu okazało, administratorzy zainstalowali jakiegoś patcha, w efekcie pojawiły się problemy bodajże z DNS a te zaburzyły działanie funkcji należącej do pewnej zewnętrznej biblioteki (zresztą wołanej tylko dla celów diagnostycznych) - która zdecydowała się zwracać 0...

Zabezpieczenie jest stosunkowo proste - trzeba napisać metodę

    inline string cstr2string(const char *c)
    {
        return c ? c : "";
    }

i pisać zawsze

    string s = cstr2string(some_fun());
komentarze obsługiwane przez Disqus