strange problem in libc: free invalid pointer, but valgrind doesn't show it.

Linda A. Walsh gcc@tlinx.org
Wed Aug 13 16:40:00 GMT 2014


Jonathan Wakely wrote:
> 
> There's no rvalue on line 295, but yes, the size of the target will
> be adjusted to the required size before copying the elements from the
> source.
----
   What do you call it?  fields_ is a valarray holding the latest dataset
returned by the measuring routines.  In this case, as verified by print output
in the first post, it has 3 members.  As it is the RH value of an assignment,
I thought it would be called an rvalue?

> 
> The error happens inside valarray<T>::operator(const valarray<T>&)
> when freeing the old storage of the target object (which in your case
> is samples[0].D). The pointer that object owns is clearly invalid:
> 
> *** Error in `./xosview': free(): invalid pointer: 0xbabababababababa ***
> 
> So my best guess is that samples[0].D was never initialized, or was
> already freed. Is samples just a block of uninitialized memory that
> has never had constructors run for its elements?
----
   You really don't wanna know, as I thought that had to be
the case as well.  *gulp*...But right above this... well, fragments
here and there...


in the ".h" file we have
vector <Samp64> samples;  (so starts off @ size=zero). <<==crux of argument

(I.e. if the above declaration doesn't result in a vector of size()
zero, I still have a hidden problem.)

Samp64 is a trivial structure with a time and the "D" (Data) valarray, but
would have size undefined if samples was size 0.

struct u64_sample{
   Timespec samp_time;
   valarray <uint64_t> D.
};

---in the code file

Just above that assignment was this line:

if (samples_collected() < graphNumSamples())
    samples_collected(samples_collected()+1);
samples_collected is *based* on the *size* of samples,
whereas graphnumSamples == the capacity of the vector <samp64>samples.

The controlling routines:
...
pr -W 125 -e$'\009'2 -t -T -n fieldmetergraph.cc|less
....
50 int FieldMeterGraph::graphNumSamples(int gns) {
51   if (gns != INT_MIN) {
          samples.reserve(gns); reset_samp_widthNper_col(); }
52   return samples.capacity();          // i.e. here, gNS returns capacity,the
                                         ".h" file has a default parm of INT_MIN
                                          as being an unlikely value for a
                                          capacity.  ;-)
53 }
54                    // in next sub, samples_collected returns samples.size()
                       // by default, else it is set via the passed param
55 int FieldMeterGraph::samples_collected(int sc) {
56   if (sc != INT_MIN) {
57     int oldsize = samples.size();      // where I rely on previous size
                                           // being 0 (in the initial case),
58     if (sc < 0 || sc == oldsize) return oldsize;  // thus new value is 1
59     if (sc > oldsize) {                // so "1>0" in first execution
60       samples.resize(sc);              // space to samples increases by 1
                                           for each sample_collected (not that
                                           I try to be too clever, I hope)
61       for (int i = oldsize; i < sc; ++i) { // now loop through the newly
                                                allocated member(s) of
                                                'samples. and init them to
                                                'sane' values...
62         samples[i].D.resize(MeterFields());  //the Data size array gets set
                                                 to #MeterFields
                                                 (3 in earlier prints)
                                                 fake in a value of 1 for
                                                 idlefield(defaults to last ]
                                                 member of VA)
63         samples[i].D[idlefield(samples[i].D)]=1;
64       }
65     }
66     reset_samp_widthNper_col();            // reset some ratios based on
                                               graph with & # samples
67   }
68   return samples.size();
69 }
                                               // class constructor, bad
                                               inputs are weeded out.
70
71 FieldMeterGraph::FieldMeterGraph(XOSView * const parent,
72     int numfields, const char *title, const char *legend,
73     bool docaptions,bool dolegends,bool dousedlegends) :
74   FieldMeter(parent, numfields, title, legend, docaptions,
75     dolegends, dousedlegends) {
76   lastWinState = OBSCURED;
77   int tmp = getIntResource("graphNumSamples");
78   if (!tmp) tmp = getIntResource("graphNumCols");
79   if (tmp)  graphNumSamples(tmp);
80   if ( numfields<=0 || graphNumSamples()<=0 ) {
81     printf("tmp=%d, numfields=%d, samples=%d, need positive!\n",
82         tmp, numfields, graphNumSamples());
83     printf("samples.max_size=%d, samples.cap=%d\n",samples.max_size(),
84             samples.capacity());
85     exit(3);
86   }
87   cm=Cmeter();  //debug
88 }

So my response on setting of +1 to the samples_collected resulted in
my self-comment "bakana!  impossible! -- it can't be unintialized
at that point.   So have engaged in other, but related code refatory
(like exanding dratio class and using it instead of integer truncs
in more places).

my 'dratio' class holds 2 numbers to allow me to do math on fractions
without resorting to floating point.

So given that, do you still think its the same problem?  I.e. did
I miss something?

Thanks, and sorry for the long winded explaination but in cases
like this not glazing over parts can often be helpful.





More information about the Libc-help mailing list