std::vector<double> destruction throws sigabrt
Asked Answered
T

3

6

I have a std::vector<double> In which GDB shows it containing these values:

Wph <5 items>            vector<double>
    [0] 10.750281685547618      double
    [1] 0.0053087812248281997   double
    [2] 4.2807534148705719e-08  double
    [3] 5.7427427663508097e-07  double
    [4] 0                       double

Upon automatic destruction when the function is exiting, it throws a SIGABRT.

0   raise   raise.c 64  0x7fffeec5ad05  
1   abort   abort.c 92  0x7fffeec5eab6  
2   __libc_message  libc_fatal.c    189 0x7fffeec93d7b  
3   malloc_printerr malloc.c    6283    0x7fffeec9fa8f  
4   _int_free   malloc.c    4795    0x7fffeec9fa8f  
5   __libc_free malloc.c    3738    0x7fffeeca38e3  
6   __gnu_cxx::new_allocator<double>::deallocate    new_allocator.h 95  0x457828    
7   std::_Vector_base<double, std::allocator<double> >::_M_deallocate   stl_vector.h    146 0x45567e    
8   std::_Vector_base<double, std::allocator<double> >::~_Vector_base   stl_vector.h    132 0x4542b3    
9   std::vector<double, std::allocator<double> >::~vector   stl_vector.h    314 0x453a96

What's going on?

  int data = 0;
  vector<double> Wph;
  Wph.resize(mydata.data.size());

  for (size_t t = 0; t < mydata.t.size(); t++)
  {
    double t0 = (PI / 180.0) * mydata.t[i];

    for (size_t p = 0; p < mydata.p.size(); p++)
    {

      double _Wph = 5; //arbitrary math
      Wph[data] = _Wph;

      data++;
    }
  }

struct mydata
{
  vector<double> t, p;
  vector<point> data;
};
Tidbit answered 26/7, 2012 at 17:27 Comment(12)
This is impossible to answer in its current form (without a lot of guess work). Consider adding a complete and minimal example program which exhibits your problem.Merchant
__libc_message is trying to give you a message. What's it print out?Moiety
Also, see sscce.orgSpurgeon
@Moiety *** glibc detected *** free(): invalid next size (fast): 0x000000000084e9c0 ***Tidbit
And size of mydata.data, mydata.t, mydata.p?Clarence
You sure that the data index doesn't overflow? valgrind might help debugging bad memory access.Bower
@Clarence data = 5, p = 2, t = 3Tidbit
The heap is corrupted and when the destructor of your vector runs it cannot give back the memory to the free list. The actual error is not in the code you have posted but somewhere else.Fakir
@Fakir How could the heap be corrupt? Nothing in this function is being allocated onto the heap..Tidbit
@Drise: Where does std::vector got the memory from when you call resize()?Fakir
@Fakir Good question. One I don't know how to answerTidbit
@Fakir why cannot the memory be given back to the free list?Jamshid
H
3

Please make sure mydata.data.size() == mydata.t.size() * mydata.p.size().

You assigned mydata.t.size() * mydata.p.size() values into a vector with mydata.data.size() elements. That's an array bound write.

Maybe you should try vector::push_back() instead. That is,

vector<double> Wph;

for (size_t t = 0; t < mydata.t.size(); t++)
{
  double t0 = (PI / 180.0) * mydata.t[i];

  for (size_t p = 0; p < mydata.p.size(); p++)
  {
    double _Wph = 5; //arbitrary math
    Wph.push_back(_Wph);
  }
}
Hedveh answered 26/7, 2012 at 17:39 Comment(5)
It does not. data = 5, p = 2, t = 3Tidbit
shouldn't it be mydata.data.size() == mydata.t.size() * mydata.p.size() ?Lichenin
@yurikilochek I made a mistake. I've fixed it through editing.Hedveh
@Timrau, push_back fixed it. This is someone else's code that I'm trying to figure out. I don't know why they decided to use operator[].Tidbit
@Tidbit Probably for efficiency reasons and it went wrong out of lack of STL experience. Use reserve instead of resize and then push_back. This will keep it to one allocation and be safe.Abner
C
0

data = 5, p = 2, t = 3

  for (size_t t = 0; t < mydata.t.size(); t++)
  {
    double t0 = (PI / 180.0) * mydata.t[i];

    for (size_t p = 0; p < mydata.p.size(); p++)
    {

      double _Wph = 5; //arbitrary math
      Wph[data] = _Wph;

      data++;
    }
  }

So, you have double loop. And you have 6 iterates... so memory corrupt will be on t == 2 and p == 1, because you will try to do Wph[5] = _Wph and maximum legal index for Wph if its size == 5 is 4.

Clarence answered 26/7, 2012 at 17:44 Comment(0)
T
0

You are making Wph too small, I suspect. We don't know what mydata.data.size() is, but I'm guessing that it is too small.

From the code, it looks like the correct size is

  Wph.resize(mydata.p.size() * mydata.t.size());

However in C++ we try to write defensive code so mistakes like that are harder to make.

  vector<double> Wph;

  for (size_t t = 0; t < mydata.t.size(); t++)
  {
    double t0 = (PI / 180.0) * mydata.t[t];

    for (size_t p = 0; p < mydata.p.size(); p++)
    {
      double _Wph = 5; //arbitrary math
      Wph.push_back(_Wph);
    }
  }

If you must pre-allocate the size, then at least change

      Wph[data] = _Wph;

to

      Wph.at(data) = _Wph;

at() works the same as [], except that at() checks that you aren't past the end of the array and throws an exception.

Tenor answered 26/7, 2012 at 18:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.