Hello everyone. I am experienceing some rather strange behaviour regarding the instantiation of an object. It's a templated custom array type object, something like this.

template <class T> class Array
{
   public:

      // Construction/destruction.
      Array( void );
      Array( unsigned int size );
      Array( const Array<T> &array );
      ~Array( void );

      // Public members.
      unsigned int size( void ) const;

      // Operator overloads.
      const Array<T> &operator = ( const Array<T> &array );

   private:

      // Private member variables.
      T *array_;
      unsigned int size_;
};

I then have another class that is to perform a simple difference operation on an Array<double> type object.

The function in my difference class looks like this. I've removed the actual meat of it for clarity but the error occurs before all of that anyway.

Array<double> Difference::Differentiate( const Array<double> &array )
{
   Array<double> tempArray( array.size() - 1 );

   return( tempArray );
}

Now to my problem. After instantiation of the object tempArray it's member variables array_ and size_ are invalid. size_ in this case should be 9 as array.size_ = 10. If I use GDB to analyse tempArray.size_ from within the Differentiate() member function it's showing a value of 4253902!

Now, the strange thing is, I know my constructor for Array<double> is working correctly because if I step into the creation of tempArray the member variables are setup correctly, but upon return from the constructor the member variables are no longer the same.

Has anybody seen behaviour like this? I'm suspecting a stack corruption maybe. I have been running with libDUMA though so it should hopefully rule that out.

Any help is greatly appreciated!

Recommended Answers

All 6 Replies

Ok, I think this might a non-issue or a tools problem or more likely a problem with the person using them, aka me!

The actual code runs and works ok. I have a loop in the Differentiate() function that reads in the size of tempArray and it loops 9 times. Except that GDB tells me the value of that variable is 4253902.

I have seen this behaviour before when using optimisation, but that's turned off by using the -O0 switch. I must be using it wrong so if anyone knows why GDB is doing this let me know!

I'm using version "GNU gdb (GDB) 7.1-ubuntu" of GDB and version "g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3" on Ubuntu "2.6.32-24-generic #42-Ubuntu SMP Fri Aug 20 14:21:58 UTC 2010 x86_64 GNU/Linux"

How do you know if its working correctly? It looks like a problem with improper initialization. How about you post more code so we can take a look.

I'm pretty sure my initialisation is ok but do correct me if I'm wrong! The rellevant constructor is this one

template <class T> Array<T>::Array( unsigned int size )
{
   array_ = NULL;
   size_ = 0;

   // Allocate memory.
   array_ = new T[ size ];
   if( array_ == NULL )
      assert( 0 ); // Crappy use of assert.

   size_ = size;

   if( pthread_mutex_init( &mutex_, NULL ) != 0 )
   {} // TODO Error.
}

...and the full Differentiate() function.

Array<double> Difference::Differentiate( const Array<double> &array )
{
   Array<double> tempArray( array.size() - 1 );
   unsigned int i = 0;

   if( array.size() > 1 )
   {
      firstElement_ = array.getAt( 0 );

      for( i=1 ; i<array.size() ; i++ )
         tempArray.setAt( i - 1, array.getAt( i ) - array.getAt( i - 1 ) );
   }

   return( tempArray );
}

The reason I know it's working is the the for loop in the above function is executing 9 times which is correct. If the value being used was as read from GDB it would be cycling 4253902 times and probably seg fault on an array index out of bounds. Also I have a test harness which exercises the functions with known patterns and results and these are all correct.

It's definitely a tools issue. If I add a printf like this

Array<double> Difference::Differentiate( const Array<double> &array )
{
   Array<double> tempArray( array.size() - 1 );
   unsigned int i = 0;

   printf( "Array size = %d\n", tempArray.size() );

   if( array.size() > 1 )
   {
      firstElement_ = array.getAt( 0 );

      for( i=1 ; i<array.size() ; i++ )
         tempArray.setAt( i - 1, array.getAt( i ) - array.getAt( i - 1 ) );
   }

   return( tempArray );
}

It prints "Array size = 9" however, if I break in with GDB, and do this after the tempArray has been created I get the following.

(gdb) print tempArray.size_
$1 = 4254684

Could it be something to do with copy relocation? the Array object is defined in a separate library but it's statically linked for now to my test harness? (where Differentiate() gets exercised)

I'm not an expert with this, but I have one idea / suggestion. This value of 4254684 looks a lot like a pointer value (converted to integer). Is it possible that you have a binary compatibility problem? Did you make sure that the static library in which the Array class template is instantiated into Array<double> is actually compiled with all the exact same compiler options? Maybe you can try to output via a member function (which is not as sensitive to binary compatibility problems) the value in integer form of the pointer array_. Just use a printf like you did for size() but for the pointer and compare that to the value that GDB outputs for the data member size_. I am suggesting that because it would explain why the function size() outputs the right value while GDB finds the wrong one. If binary compatibility is the issue, that behavior makes sense (GDB assumes a different binary footprint for the class and thus, looks at the wrong place for the value of size_, possibly where the pointer array_ is located in memory).

Hi There,

Yes that is a good idea indeed. I did a verbose compile of the code and the only difference as a -rdynamic switch. This is now corrected and the problem still presents itself.

I did as you suggested though just to make sure. The array_ pointer is actually still very different to the value returned by GDB and in the size_ variable.

I'm more and more convinced this is a GDB problem. I found this http://www.experts-exchange.com/Programming/Languages/CPP/Q_21507511.html which appears to be a similar problem to what I am getting except that my code is exacerbated by templates.

After some searching around and googling it looks like GDB does not handle C++ well in some cases and is made worse with templates. I think I'll raise a bug against GDB and see what the community suggest.

Thanks for all the replies, further comments are welcomed!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.