Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

overloading problem 1

Status
Not open for further replies.

maur3r

Technical User
Aug 28, 2006
34
0
0
PL
I am writing an application which is supposed to implement polynomials. It involves dynamic memory allocation, therefore I check it with valgrind. Once I noticed the following problem and I have no idea how to fix it
Code:
double poly::operator() (const double& value)
{
double tmp;
  for(unsigned i=0;i<=degree;i++)
    tmp+=values[i]*value;

  return tmp;
}

ostream & operator << (ostream & o, const poly & p)
{
  for (unsigned i=0;i<=p.degree;i++){
	o << p[i];
	o << "(X^"<<i<<")";
     if(i+1<=p.degree) 
	  if((p.values[i+1]>=0)&&(i<p.degree))
            o << "+";
      }
  return o;
}
When using valgrind I receive
Code:
==6045== Conditional jump or move depends on uninitialised value(s)
==6045==    at 0x1BA819CD: _IO_file_xsputn (in /lib/tls/libc-2.3.5.so)
==6045==    by 0x1BA77561: fwrite (in /lib/tls/libc-2.3.5.so)
==6045==    by 0x1B992496: (within /usr/lib/libstdc++.so.6.0.5)
==6045==    by 0x1B991E79: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_float<double>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, char, double) const (in /usr/lib/libstdc++.so.6.0.5)
==6045==    by 0x1B9922CB: std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::do_put(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, double) const (in /usr/lib/libstdc++.so.6.0.5)
==6045==    by 0x1B995CC5: std::ostream::operator<<(double) (in /usr/lib/libstdc++.so.6.0.5)
==6045==    by 0x8048B61: main (testpoly.cpp:28)
==6045==
==6045== Syscall param write(buf) points to uninitialised byte(s)
==6045==    at 0x1BADDA63: write (in /lib/tls/libc-2.3.5.so)
==6045==    by 0x1BA8187E: _IO_file_write (in /lib/tls/libc-2.3.5.so)
==6045==    by 0x1BA802A4: (within /lib/tls/libc-2.3.5.so)
==6045==    by 0x1BA803BE: _IO_do_write (in /lib/tls/libc-2.3.5.so)
==6045==    by 0x1BA80C9D: _IO_file_overflow (in /lib/tls/libc-2.3.5.so)
==6045==    by 0x1BA82413: __overflow (in /lib/tls/libc-2.3.5.so)
==6045==    by 0x1BA7DD58: putc (in /lib/tls/libc-2.3.5.so)
==6045==    by 0x1B99281B: (within /usr/lib/libstdc++.so.6.0.5)
==6045==    by 0x1B996517: std::ostream::put(char) (in /usr/lib/libstdc++.so.6.0.5)
==6045==    by 0x1B996621: std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&) (in /usr/lib/libstdc++.so.6.0.5)
==6045==    by 0x1B99388E: std::ostream::operator<<(std::ostream& (*)(std::ostream&)) (in /usr/lib/libstdc++.so.6.0.5)
==6045==    by 0x8048B72: main (testpoly.cpp:28)
==6045==  Address 0x1B903026 is not stack'd, malloc'd or (recently) free'd
Line 28 in testpoly contains following
cout << "Value of polynomial P1 at point 3.14: " << val << endl;
where double val = P1(3.14);
Problem vanishes when i transform operator () function in th e following way
Code:
double poly::operator() (const double& value)
{
double tmp;
  for(unsigned i=0;i<=degree;i++)
    tmp+=values[i]*value;

  return 0 /*or some other constant*/;
}
I am not very experienced in C++ programming and valgrind therefore I will appreciate any kind of help.

Martin
 
> for(unsigned i=0;i<=degree;i++)
Well if you've followed usual array syntax, and have something like
[tt]double values[degree];[/tt]
or
[tt]double *values = new double[degree];[/tt]

Then your loop steps off the end by one place (and thus trashes someone elses memory).

[tt]for(unsigned i=0;i<degree;i++)[/tt]
Is the idiomatic construct for looping over an array.

--
 
ALWAYS initialize your variables, because C/C++ won't do it for you!
Code:
double poly::operator() (const double& value)
{
double tmp;  // Uninitialized!
  for(unsigned i=0;i<=degree;i++)
    tmp+=values[i]*value;

  return tmp;
}
This function has undefined behavior since tmp starts with whatever garbage value was already sitting in memory. Then you += to tmp and return it, so it will almost never return the correct answer.
 
Well if you've followed usual array syntax, and have something like
double values[degree];
or
double *values = new double[degree];
In my code *values are initialized in following way
double *values = new double[degree+1];
But when I initialize tmp in following way
Code:
double tmp=0;
everything works fine. It's pretty amazing how little things can destroy the whole code :) I want to thank both of you for interest and especially you cpjust for solution.

Regards, Martin

(OS and comp.)
using Linux and gcc
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top