This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ 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]

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


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


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