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

Jonathan Wakely jwakely@redhat.com
Wed Aug 13 17:02:00 GMT 2014


[Removing libc-help as this is probably nothing to do with libc.]


On 13/08/14 09:40 -0700, Linda A. Walsh wrote:
>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?

No, fields_ is an lvalue.

http://thbecker.net/articles/rvalue_references/section_01.html

The fact it happens to be on the RHS of an assignment in that
expression doesn't mean it's 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.)

That's a vector of size zero.

>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.

Initially size() and capacity() are both zero, so the condition is
false and you won't resize the vector. That means samples[0].D is
undefined behaviour.

Could that be the problem?

>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?

Dunno. Try compiling with -D_GLIBCXX_DEBUG to turn on debugging checks
in std::vector.

Alternatively, replace all uses of samples[x] with samples.at(x) to
check you're only accessing valid elements.

Unless you really, really need it I would not use valarray either.
std::vector is a better choice for most uses, and safer and easier to
use. valarray is subtle and hard to use.

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

Indeed, I hate being asked to debug a single line with no context.



More information about the Libstdc++ mailing list