Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

address changes on function call

0 views
Skip to first unread message

Evan

unread,
Jul 28, 2009, 1:55:17 PM7/28/09
to
Hi everyone,

I am experiencing the following strange and fatal behavior. Given the
function below:

VectorN MatrixN::get_row1(unsigned i) const
{
VectorN v;
get_row2(i, v);
return v;
}

The variable 'v' has the address '0x7ffff8c4d988'. Stepping through
gdb to get_row2(), where 'v' is passed in by reference, reports:

MatrixN::get_row2 (this=0x7fff31c34940, i=0, result=@0x7fff31c34a50)

The address of 'v' (called 'result' in get_row2) has suddenly
changed! Even stranger, 'print v' while in get_row1() indicates:

$4 = {
_vptr.VectorN = 0x7fff31c34a50,
...
}

So, vptr (I assume this has to do with the fact that VectorN has
virtual methods) actually points to the address that is passed to
get_row2()! Regardless of this occurrence, any changes that I make to
'result' in get_row2() do not show up as they should in 'v' in get_row1
().

Unfortunately, this behavior is not reproducible in a small test
program, just in my library of 70k lines of code :)

Any elucidation about what might be happening would be greatly
appreciated.

Thanks!
Evan

Pascal J. Bourguignon

unread,
Jul 28, 2009, 6:46:34 PM7/28/09
to
Evan <edru...@gmail.com> writes:

You should show us the definition of VectorN and the signature of
get_row2.

This could occur if VectorN inherit from multiple superclasses, and
get_row2 takes one in parameter as reference. Other cases are
certainly possible.

--
__Pascal Bourguignon__

Evan

unread,
Jul 28, 2009, 6:57:57 PM7/28/09
to
Right, unfortunately, that does not seem to be the case.
Nevertheless, here is the signature of get_row2():

MatrixN
{
...
void get_row2(unsigned i, VectorN& result) const;
...
}

and here is the definition of VectorN:

class VectorN
{
public:
template <class ForwardIterator>
VectorN(ForwardIterator begin, ForwardIterator end);

VectorN();
VectorN(unsigned N);
VectorN(const VectorN& source);
VectorN(VectorN& source);
VectorN(const Vector2& v);
VectorN(const Vector3& v);
VectorN(const SVector6& v);
VectorN(unsigned N, const Real* array);
VectorN(unsigned N, boost::shared_array<Real> array);
static VectorN construct_variable(unsigned N, ...);
virtual ~VectorN() {}
virtual Real dot(const VectorN& v) const { return dot(*this, v); }
static Real dot(const VectorN& v1, const VectorN& v2);
VectorN& normalize() { assert(norm() > 0.0); operator*=(1.0/norm
()); return *this; }
static VectorN normalize(const VectorN& v);
unsigned size() const { return _len; }
static Real norm(const VectorN& v);
static Real norm_sq(const VectorN& v) { return VectorN::dot(v,
v); }
Real norm() const { return norm(*this); }
Real norm_sq() const { return norm_sq(*this); }
static VectorN one(unsigned N);
MatrixN* outer_prod(const VectorN& v, MatrixN* m) const { return
outer_prod(*this, v, m); }
static MatrixN* outer_prod(const VectorN& v1, const VectorN& v2,
MatrixN* m);
static VectorN concat(const VectorN& v1, const VectorN& v2);
static VectorN& concat(const VectorN& v1, const VectorN& v2,
VectorN& result);
VectorN& augment(const VectorN& v);
VectorN& resize(unsigned N, bool preserve = false);
VectorN& set_zero();
VectorN& set_one();
VectorN get_sub_vec(unsigned start_idx, unsigned end_idx) const;
VectorN& get_sub_vec(unsigned start_idx, unsigned end_idx,
VectorN& v) const;
VectorN& set_sub_vec(unsigned start_idx, const VectorN& v);
static VectorN zero(unsigned n);
bool is_finite() const;
VectorN& negate();
VectorN& operator=(const Vector3& source);
VectorN& operator=(VectorN& source);
VectorN& operator=(const VectorN& source);
VectorN operator+(const VectorN& v) const;
VectorN& operator+=(const VectorN& v);
VectorN operator-(const VectorN& v) const;
VectorN& operator-=(const VectorN& v);
VectorN operator*(Real scalar) const;
VectorN& operator*=(Real scalar);
VectorN operator/(Real scalar) const;
VectorN& operator/=(Real scalar) { return operator*=(1.0/
scalar); }
VectorN operator-() const;
Real& operator[](const unsigned i) { assert(i < _len); return _data
[i]; }
Real operator[](const unsigned i) const { assert(i < _len); return
_data[i]; }
Real* data() { return _data.get(); }
const Real* data() const { return _data.get(); }
bool operator<(const VectorN& v) const;
bool operator==(const VectorN& v) const;
static bool epsilon_equals(const VectorN& v1, const VectorN& v2,
Real epsilon);
bool epsilon_equals(const VectorN& v, Real epsilon) const;
static VectorN parse(const std::string& s);

template <class ForwardIterator>
VectorN select(ForwardIterator idx_begin, ForwardIterator idx_end)
const;

template <class ForwardIterator>
VectorN& select(ForwardIterator idx_begin, ForwardIterator
idx_end, VectorN& v) const;

template <class ForwardIterator>
VectorN& set(ForwardIterator idx_begin, ForwardIterator idx_end,
const VectorN& v);

/// Sets this to a n-length zero vector
VectorN& set_zero(unsigned n) { return resize(n).set_zero(); }

/// Sets this to a n-length ones vector
VectorN& set_one(unsigned n) { return resize(n).set_one(); }

/// Gets iterator to the start of the data
Real* begin() { return &_data[0]; }

/// Gets constant iterator to the start of the data
const Real* begin() const { return &_data[0]; }

/// Gets iterator to the end of the data
Real* end() { return &_data[0] + _len; }

/// Gets constant iterator to the end of the data
const Real* end() const { return &_data[0] + _len; }

/// Copies the source vector
VectorN& copy(const VectorN& source) { return operator=(source); }

/// Swaps this vector with another
void swap(VectorN& source) { std::swap(_data, source._data);
std::swap(_len, source._len); std::swap(_capacity,
source._capacity); }

protected:
static bool rel_equal(Real x, Real y);
boost::shared_array<Real> _data;
unsigned _len;
unsigned _capacity;
}; // end class


Thanks for looking at this. I did try compiling with three different
versions of g++ (4.1, 4.2, and 4.3). All give the same problem. Very
perplexing...

Thanks again,
Evan

0 new messages