Saturday, January 24, 2009

SIGSEGV on statement with std::string variable, G++.

If you have error report like

Program received signal SIGSEGV, Segmentation fault.
0xb7d2be69 in __gnu_cxx::__exchange_and_add () from /usr/lib/libstdc++.so.6
(gdb) where
#0 0xb7d2be69 in __gnu_cxx::__exchange_and_add () from /usr/lib/libstdc++.so.6
#1 0xb7d0dfcc in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string () from /usr/lib/libstdc++.so.6
...

or

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb746b6d0 (LWP 9469)]
0xb7c5ce69 in __gnu_cxx::__exchange_and_add () from /usr/lib/libstdc++.so.6
(gdb) where
#0 0xb7c5ce69 in __gnu_cxx::__exchange_and_add () from /usr/lib/libstdc++.so.6
#1 0xb7c3e8e4 in std::string::assign () from /usr/lib/libstdc++.so.6
#2 0xb7c3e944 in std::string::operator= () from /usr/lib/libstdc++.so.6
...

or something similar,
check that memory under string variable isn't corrupted.
In my case the problem was with zeroed memory. In Visual Studio I used the ugly but effective construction like

string a;
memset(&a, 0, sizeof(a));

and I didn't have problems with it. But in g++ and in general I must be more accurate.

2 comments:

  1. It's not "ugly but effective", it's "ugly and completely useless". Default constructor has already initialized string to valid empty value.

    ReplyDelete
  2. Yes, you're absolutely right.
    It seems I forgot to include the example where I used it.
    For instance, I have
    struct Struct
    {
    bool Bools[10];
    float Floats[10];
    string Strings[10];
    ...
    };

    In the constructor call I want to initialize all Struct members with zeros/empty values (all Bools, Floats, Strings etc) at once.
    Struct::Struct()
    {
    memset(this, 0, sizeof(Struct));
    }

    As I wrote it works in Windows, but crashes in Linux.
    So the correct way to do so will be:

    Struct::Struct()
    {
    char bytes[10*sizeof(string)];
    memcpy(bytes, Strings, sizeof(bytes));
    memset(this, 0, sizeof(Struct));
    memcpy(Strings, bytes, sizeof(bytes));
    }

    ReplyDelete