Help with pushing back a struck to a vector

I’m having the hardest time debugging this… The gist is that I’m trying to push_back a struct of type “P_Peak” defined as

struct P_Peak{ // stored peak information unsigned int chan_num; int start; unsigned int length; double area; double height; double baseline; TH1D data; };

to a vector with a bit of code like within a class method. The object “peak” is a vector of P_Peak:

void My_Pulse::ConvertChPeak( Ch_Peak *p, My_Channel *ch){
    // This function takes a "Ch_Peak" and converts it to a "P_Peak".  The histogram data is converted
    // form ADC to phe. The baseline is converted form ADC to mV.

    double Gain = ch->Gain;
    double R = ch->Impedance;
    double timeRes = ch->timeResolution;

    P_Peak q;
    q.chan_num = p->chan_num;
    q.start = p->start;
    q.length = p->length;
    q.baseline = p->baseline *2000./16384;
    char str[40];
    sprintf (str, "peak_e%is%ip%i", evt_num, q.start, (int)peak.size() ); = TH1D(str, str, q.length, timeRes*q.start, timeRes*(q.start+q.length));

    for (unsigned int i=1; i<=p->length; i++){
        double d = p->data.GetBinContent(i);
        double temp = (p->baseline-d)*2000./16384; // converts ADC to mV
        temp *= timeRes/ (1.6e-19 * 1e3 * R * Gain); // converts mV to phe
        if ( !(d == 0 || d > 16384) )
  *(q.start+i), 1.0*temp);


The error occurs at the push_back line at the very end. It happens after about 8 loops of this being called successfully. The error is:

[code]that might help us fixing this issue.

#5 0x0000000100122a78 in TList::FindObject ()
#6 0x000000010012064d in THashList::Remove ()
#7 0x00000001013d1312 in TH1::~TH1 ()
#8 0x0000000100007279 in P_Peak::~P_Peak (this=0x1029ca960) at My_Pulse.h:11
#9 0x0000000100007290 in std::_Destroy<P_Peak> (__pointer=0x1029ca960) at stl_construct.h:107
#10 0x00000001000072ad in std::__destroy_aux<P_Peak*> (__first=0x1029ca960, __last=0x1029cb080) at stl_construct.h:122
#11 0x00000001000072e5 in std::_Destroy<P_Peak*> (__first=0x1029c9400, __last=0x1029cb080) at stl_construct.h:155
#12 0x000000010000758b in std::_Destroy<P_Peak*, P_Peak> (__first=0x1029c9400, __last=0x1029cb080) at stl_construct.h:182
#13 0x0000000100010ca2 in std::vector<P_Peak, std::allocator<P_Peak> >::_M_insert_aux (this=0x102906640, __position={_M_current = 0x1029cb080}, __x=
0x7fff5fbfc360) at vector.tcc:293
#14 0x0000000100010ea5 in std::vector<P_Peak, std::allocator<P_Peak> >::push_back (this=0x102906640, __x=
0x7fff5fbfc360) at stl_vector.h:608
#15 0x000000010000dbc3 in My_Pulse::ConvertChPeak (this=0x102906638, p=0x102976b78, ch=0x102880940) at My_Pulse.cxx:295
#16 0x000000010000e044 in My_Pulse::AddPeak (this=0x102906638, p=0x102976b78, ch=0x102880940) at My_Pulse.cxx:125
#17 0x000000010000267c in main (argc=2, argv=0x7fff5fbfdba8) at Make_EVT_Tree.cxx:254


Without posting all my code (I could if you’d like), what kind of bug would cause this error? I’ve been googling for hours without success. I’ve run it through gdb and valgrind and I don’t seem to get any new info.

I read something on that led me to find a problem:

A reallocation invalidates all previously obtained iterators, references and pointers to elements of the vector.

I think what is happening is that when the vector changes shape at various points in the rest of the code, although the P_Peak doesn’t any pointers in it, the histogram it carries does and those seem to be lost. Sticking in


at the top of the method seems to get me past this seg fault and on to another.

TH1D class has available copy constructor and copy-assignment operator. It’s copy constructible ==
it’s ok for vector. And you can push_back a histogram without any problem. And you do not have to care about any pointer inside TH1D - it’s TH1D’s business to manage them correctly.
So, the fragment of code you demonstrated is not enough to reproduce the problem. You found a workaround with reserve, but, probably, just hid the problem instead of solving it.

Thanks tpochep. In trying to fix it I’ve butchered the code a bit. I’ll upload it when I get it clean enough to illustrate the problem without a thousand cout’s cluttering the screen and without kludges that have “hidden” the problem!

Ok, good. And just to check my own words, I’ve wrote a simple and stupid macro, which I compiled (.L hv.C++)
and it does not crush, though contains something similar to your code.

#include <vector>

#include <TString.h>
#include <TH1.h>

struct A
  int i;
  TH1D h;

void hv()
  std::vector<A> v;
  for(int i = 0; i < 10000; ++i)
    const TString name(TString::Format("aa%d", i));
    A a;
    a.i = 10;
    a.h = TH1D(name.Data(), name.Data(), 100, -1., 1.);