This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

slice valarrays with std::string -> segfault


Please consider the program below (backtrace included (gcc 4.0.2
(Ubuntu))). The program crashes when doing a std::slice on a valarray
containing a structure with a string element in it.

Is what I am doing there undefined behaviour? I've read 26.3.4 from
the standard but got no clues.

As you can see in the backtrace the segfault happens when trying to
assign this string:

(gdb) print *__a
...
  y = {
    static npos = 18446744073709551615, 
    _M_dataplus = {
      <std::allocator<char>> = {
        <__gnu_cxx::__mt_alloc<char,__gnu_cxx::__common_pool_policy<__gnu_cxx::__pool, true> >> = {
          <__gnu_cxx::__mt_alloc_base<char>> = {<No data fields>}, <No data fields>}, <No data fields>}, 
      members of std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Alloc_hider: 
      _M_p = 0x2aaaaadb9958 ""
    }

to this string:

(gdb) print *__b
...
  y = {
    static npos = 18446744073709551615, 
    _M_dataplus = {
      <std::allocator<char>> = {
        <__gnu_cxx::__mt_alloc<char,__gnu_cxx::__common_pool_policy<__gnu_cxx::__pool, true> >> = {
          <__gnu_cxx::__mt_alloc_base<char>> = {<No data fields>}, <No data fields>}, <No data fields>}, 
      members of std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Alloc_hider: 
      _M_p = 0x0
    }

I am not sure why *__b is a 0x0-string, and who should be responsible
to initialize it correctly (__b is initialized in the C++ library). It
is mandated by the standard that only POD types are allowed in a
valarray?

Thanks,

(The program crashes with gcc 3.x und gcc 4.x, it works with Visual
Studio though :-().

--8<---------------cut here---------------start------------->8---
#include <valarray>
 
struct element
{
  int x;
  std::string y;
 
  element ()
  {
    x = 0;
    y = "";
  }
 
  element const & operator = (element const & e)
  {
    if (this != &e)
    {
      x = e.x;
      y = e.y; // Why is this.y = 0x0 ?
    }
    return *this;  
  }
};
 
int main (int argc, char **argv)
{
  std::valarray <element> y (element (), 1);
 
  std::valarray <element> z =
    std::valarray <element> (y [std::slice (0, 1, 1)]);
 
  return 0;
}

Core was generated by `./a.out'.
Program terminated with signal 11, Segmentation fault.
(gdb) bt
#0  0x00002aaaaac80d52 in __gnu_cxx::__exchange_and_add () from /usr/lib/libstdc++.so.6
(gdb) bt
#0  0x00002aaaaac80d52 in __gnu_cxx::__exchange_and_add () from /usr/lib/libstdc++.so.6
#1  0x00002aaaaac61edc in std::string::assign () from /usr/lib/libstdc++.so.6
#2  0x0000000000400c33 in element::operator= (this=0x502030, e=@0x502010) at valarray_segfault.cpp:19
#3  0x0000000000400f9f in std::__valarray_copy<element> (__a=0x502010, __n=1, __s=1, __b=0x502030) at valarray_array.h:293
#4  0x0000000000400ff9 in std::__valarray_copy<element> (__a={_M_data = 0x502010}, __n=1, __s=1, __b={_M_data = 0x502030}) at valarray_array.h:457
#5  0x0000000000401065 in valarray (this=0x7ffffffb1980, __sa=@0x7ffffffb19b0) at valarray:587
#6  0x0000000000400961 in main (argc=1, argv=0x7ffffffb1ad8) at valarray_segfault.cpp:30
(gdb) frame 3
#3  0x0000000000400f9f in std::__valarray_copy<element> (__a=0x502010, __n=1, __s=1, __b=0x502030) at valarray_array.h:293
293             *__b = *__a;
(gdb) print *__b
$1 = {
  x = 0, 
  y = {
    static npos = 18446744073709551615, 
    _M_dataplus = {
      <std::allocator<char>> = {
        <__gnu_cxx::__mt_alloc<char,__gnu_cxx::__common_pool_policy<__gnu_cxx::__pool, true> >> = {
          <__gnu_cxx::__mt_alloc_base<char>> = {<No data fields>}, <No data fields>}, <No data fields>}, 
      members of std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Alloc_hider: 
      _M_p = 0x0
    }
  }
}
(gdb) print *__a
$2 = {
  x = 0, 
  y = {
    static npos = 18446744073709551615, 
    _M_dataplus = {
      <std::allocator<char>> = {
        <__gnu_cxx::__mt_alloc<char,__gnu_cxx::__common_pool_policy<__gnu_cxx::__pool, true> >> = {
          <__gnu_cxx::__mt_alloc_base<char>> = {<No data fields>}, <No data fields>}, <No data fields>}, 
      members of std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Alloc_hider: 
      _M_p = 0x2aaaaadb9958 ""
    }
  }
}
(gdb)
--8<---------------cut here---------------end--------------->8---

-- 
--Jhair

PGP key available from public servers - ID: 0xBAA600D0


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]