CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 17
  1. #1
    Join Date
    May 2009
    Posts
    5

    Unhappy operator overloading

    hello everyone!
    I met some problems with pointer here:
    Code:
    ////////////////////////code//////////////////////////////////
    //class's declaration 
    //file FunnyString.h
    #ifndef FUNNYSTRING_H
    #define FUNNYSTRING_H
    #include <cassert>
    #include <iostream>
    
    using namespace std;
    class FunnyString
    {
    	friend istream &operator>>( istream&, FunnyString& );
    	friend ostream &operator<<( ostream&, FunnyString&) ;
    public:
    	FunnyString(char* = 0);
    	~FunnyString()
    	{
    		delete [] data;
    	}
    	FunnyString( FunnyString& ); //copy constructor.
    	FunnyString  operator+( FunnyString& );
    	FunnyString & operator=(  FunnyString& ); //assigment operator.
    private:
    	void SetString( char*);
    	char GetOneCharacter( const int & index )
    	{
    		assert( ( index < len ) && index>= 0 );
    		return data[index];
    	}
    	void CutBeginCharacter();
    	void SelfCutEndCharacter();
    	char* data;
    	int len;
    };
    #endif
    ///////////////////////////code///////////////////////////////////////////////
    -----------------------------code--------------------------------------------
    //FunnyString class's definition.
    //FunnyString.cpp file.
    #include "FunnyString.h"
    #include <iostream>
    #include <cassert>
    using namespace std;
    
    FunnyString::FunnyString(char *s )
    :len(strlen(s)+1)
    {
    	SetString(s);
    }
    FunnyString::FunnyString( FunnyString & s)
    {
    	SetString(s.data);
    }
    FunnyString& FunnyString::operator= (  FunnyString& s)
    {
    	if ( &s != this ) //prevent self assigment.
    	{
    		if ( s.len != len )
    		{
    			delete [] data;
    			SetString(s.data);
    		}
    	}
    	else cout << "Self assigment\n";
    	return *this;
    }
    FunnyString  FunnyString::operator+( FunnyString & s)
    {
    	FunnyString fString1(data);
    	FunnyString fString2(s.data);
            FunnyString &tmp = fString1;
    	while ( fString1.data[len-2] == fString2.data[0] )
    	{
    		fString1.SelfCutEndCharacter();
    		fString2.CutBeginCharacter();
    	}
    	strcat(fString1.data,fString2.data);
    	return tmp;
    }
    ostream& operator<< (ostream& output,FunnyString& s )
    {
    	output << s.data;
    	return output;
    }
    istream& operator>> (istream& input, FunnyString& s)
    {
    	char tmp[100];
    	input >> tmp;
    	s.data = tmp;
    	return input;
    }
    void FunnyString::SetString( char* s )
    {
    	if ( 0 != s )
    	{
    		len = strlen(s)+1;
    		data = new char[len];
    		strcpy(data,s);
    	}
    	else 
    	{
    		len = 1;
    		data = 0;
    	}
    }
    void FunnyString::CutBeginCharacter()
    {
    	char* tmp = new char[len-1];
    	for ( int i = 0; i < len - 2; i++)
    	{
    		tmp[i]=data[i+1];
    	}
    	tmp[len-2] = 0;
    	delete [] data;
    	SetString(tmp);
    	delete [] tmp;
    }
    void FunnyString::SelfCutEndCharacter()
    {
    	char* tmp = new char[len-1];
    	strncpy(tmp,data,len-2);
    	tmp[len-2] = 0;
    	delete [] data;
    	SetString(tmp);
    	delete [] tmp;	//release tmp;
    }
    -----------------------------code-------------------------------------

    The operator+ function met a pointer problem(I don't know why, I just want this function does not change the data, so I created 2 new FunnyString objects and handle them. This function return a reference of FunnyString!!!- maybe when the function end, all the data will be destruct by destructor which released the char* data, so function can not return it).But I can't prevent it. this is a operator overloading, it can not contain more parameter,so how can I return in this function?
    Last edited by HanneSThEGreaT; May 13th, 2009 at 10:44 AM.

  2. #2
    Join Date
    Nov 2006
    Location
    Essen, Germany
    Posts
    1,344

    Re: operator overloading

    I doubt you&#180;ll get any help without properly formatting your code. Code tags are [ code ] and [ /code ], all without spaces.
    - Guido

  3. #3
    Join Date
    Jul 2001
    Location
    Sunny South Africa
    Posts
    11,283

    Re: operator overloading

    What precisely is the problem, we don't know what you what you want to do, where the error occurs &#191; Please explain properly.

  4. #4
    Join Date
    May 2009
    Posts
    15

    Re: operator overloading

    Quote Originally Posted by dakotabk View Post
    hello everyone!
    I met some problems with pointer here:
    Code:
    ////////////////////////code//////////////////////////////////
    
    FunnyString  FunnyString::operator+( FunnyString & s)
    {
    	FunnyString fString1(data);
    	FunnyString fString2(s.data);
            FunnyString &tmp = fString1;
    	while ( fString1.data[len-2] == fString2.data[0] )
    	{
    		fString1.SelfCutEndCharacter();
    		fString2.CutBeginCharacter();
    	}
    	strcat(fString1.data,fString2.data);
    	return tmp;
    }
    -----------------------------code-------------------------------------

    The operator+ function met a pointer problem(I don't know why, I just want this function does not change the data, so I created 2 new FunnyString objects and handle them. This function return a reference of FunnyString!!!- maybe when the function end, all the data will be destruct by destructor which released the char* data, so function can not return it).But I can't prevent it. this is a operator overloading, it can not contain more parameter,so how can I return in this function?
    First, it is no need to use two FunnyString objects.
    Second, fString1 is a local variable so it will be destroyed when the method done. When fString1 is destroyed , its destructor is called. It mean, its data is deleted.

    Moreover, temp is a reference to fString1 , so data of temp is deleted too.

    solution :

    Code:
        
    FunnyString  FunnyString::operator+( FunnyString & s)
    {
           char* sResult = new char[s.len + this->len];
    	FunnyString fsResult;        
    
           strcpy(sResult, this->data);
           strcpy(&sResult[this->len], s.data);
    
            fsResult.data = sResult;
            return fsResult;
           
    }

  5. #5
    Join Date
    Aug 2007
    Posts
    858

    Re: operator overloading

    You really need to work on const correctness in that code.

    What I would probably do is implement an insert function, then implement operator + in terms of the insert function.

    It would look something like (warning, untested code):

    Code:
    FunnyString& Insert(size_t pos, const FunnyString& str)
    {
      assert(pos < this->len);
        
      char* temp = new char[this->len + str.len];
      
      strncpy(temp, this->data, pos - 1);
      strcat(temp, str.data);
      strcat(temp, this->data + pos);
      
      delete [] this->data;
      this->data = temp;
      this->len += str.len;
      
      return *this;
    }
    
    FunnyString operator +(const FunnyString& str) const
    {
      return FunnyString(*this).Insert(this->len - 1, str);
    }
    Last edited by Speedo; May 13th, 2009 at 02:20 PM.

  6. #6
    Join Date
    May 2009
    Posts
    5

    Re: operator overloading

    Quote Originally Posted by ptaminh View Post
    First, it is no need to use two FunnyString objects.
    Second, fString1 is a local variable so it will be destroyed when the method done. When fString1 is destroyed , its destructor is called. It mean, its data is deleted.

    Moreover, temp is a reference to fString1 , so data of temp is deleted too.

    solution :

    Code:
        
    FunnyString  FunnyString::operator+( FunnyString & s)
    {
           char* sResult = new char[s.len + this->len];
    	FunnyString fsResult;        
    
           strcpy(sResult, this->data);
           strcpy(&sResult[this->len], s.data);
    
            fsResult.data = sResult;
            return fsResult;
           
    }
    I understood what you mean. But my problem is the operator+ can not change the objects itself, so I use 2 new object to handle. And the function returns a reference of FunnyString object ( FunnyString& FunnyString:perator+() ) (sorry).
    When the function ends, destructor calls delete[], so all data is destroyed....So this function seems to can not return an object!!!!?

  7. #7
    Join Date
    May 2009
    Posts
    15

    Re: operator overloading

    Quote Originally Posted by dakotabk View Post
    I understood what you mean. But my problem is the operator+ can not change the objects itself, so I use 2 new object to handle. And the function returns a reference of FunnyString object ( FunnyString& FunnyString:perator+() ) (sorry).
    When the function ends, destructor calls delete[], so all data is destroyed....So this function seems to can not return an object!!!!?
    It can return an object because FunnyString already have copy constructor.

    The error is here

    Code:
    FunnyString  FunnyString::operator+( FunnyString & s)
    {
           char* sResult = new char[s.len + this->len - 1];
    	FunnyString fsResult;        
    
           strcpy(sResult, this->data);
           
    
           strcpy(&sResult[this->len], s.data); // Error is here
           strcpy(&sResult[this->len - 1], s.data); ; // fixed
    
            fsResult.data = sResult;
            return fsResult;
           
    }
    Because you assign len = strlen(...) + 1. It should be strlen(...).

    when you fixed the method is ok.
    Last edited by ptaminh; May 14th, 2009 at 01:03 AM.

  8. #8
    Join Date
    Oct 2000
    Location
    London, England
    Posts
    4,773

    Re: operator overloading

    You have a constructor with a default parameter to an invalid value. If someone constructs a FunnyString with its default constructor it will cause undefined behaviour (probably access violation / segmentation fault on most common systems).

  9. #9
    Join Date
    May 2009
    Posts
    5

    Re: operator overloading

    You're right. When I create an object with default constructor. eg: FunnyString a; this is an error. But I dont know how to solve it? ( I just want the default constructor will create a NULL string ).

  10. #10
    Join Date
    Apr 2007
    Location
    Mars NASA Station
    Posts
    1,436

    Re: operator overloading

    Set char* data; to valid string.
    Thanks for your help.

  11. #11
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: operator overloading

    Quote Originally Posted by dakotabk
    I just want the default constructor will create a NULL string
    Instead of declaring:
    Code:
    FunnyString(char* = 0);
    Declare:
    Code:
    FunnyString(const char* s = "");
    So, now the default constructor's call of strlen(s) will work correctly. With this in place, it looks like you should tweak the SetString member function.

    By the way, the jargon differs depending on what you are talking about, but in C and C++ "empty string" or "zero length string" would be a better term than "null string" since null is often used to refer to a null pointer constant or a null character.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  12. #12
    Join Date
    May 2009
    Posts
    5

    Talking Re: operator overloading

    I still have problems here. So, I post it all again.
    The problem is: FunnyString class overload the + operator. The operator+ works like that
    FunnyString s1("123aa");
    FunnyString s2("aa456");
    //s1+s2 = "123456"; (the two "aa" was cut).
    This class also overload some operators, so the s1 and s2 can not be changed ( in order to use later ).

    I did it like that:
    Code:
    #ifndef FUNNYSTRING_H
    #define FUNNYSTRING_H
    #include <cassert>
    #include <iostream>
    
    using namespace std;
    class FunnyString
    {
    private:
    	void SetString( const char*);
    	char* data;
    	int len;
    
    public:
    	FunnyString(const char* = "");
    	~FunnyString()
    	{
    		delete [] data;
    	}
    	FunnyString( const FunnyString& ); //copy constructor.
    	FunnyString  operator+(const  FunnyString& );
    }
    Code:
    //FunnyString class's definition.
    #include "FunnyString.h"
    #include <iostream>
    #include <cassert>
    #include <cstring>
    using namespace std;
    
    FunnyString::FunnyString(const char *s =  )
    {
    	SetString(s);
    }
    FunnyString::FunnyString( const FunnyString & s)
    {
    	SetString(s.data);
    }
    FunnyString FunnyString::operator= ( const FunnyString& s)
    {
    	if ( &s != this ) //prevent self assigment.
    	{
    		if ( s.len != len )
    		{
    			delete [ ] data;
    			SetString(s.data);
    		}
    	}
    	else cout << "Self assigment\n";
    	return *this;
    }
    FunnyString FunnyString::operator+( const FunnyString & s)
    {
            int i = 1;
    	int j = 0;
    	int count = 0;
    	while ( data[len-i] == s.data[j] )
    	{
    		++i;
    		++j;
    		++count;
    	} 	//for example: if "abcdhg" + "ghag", the count will get 2.
    	char* tmp = new char[ len + s.len - 2*count];
    	strncpy(tmp, data, len - count);
    	int k = 0;
    	for ( int i = count; i <= s.len  ; ++i )
    	{
    		tmp[len - count + k] = s.data[i];
    		++k;
    	}
    	FunnyString result;
    	result = tmp;
    	delete [] tmp;
    	return result;
    }
    void FunnyString::SetString( const char* s )
    {
    	if ( 0 != s )
    	{
    		len = strlen(s);
    		data = new char[len+1];
    		strcpy(data,s);
    	}
    	else 
    	{
    		len = 0;
    		data = 0;
    	}
    }
    The problem is: in operator+(), delete [] tmp; // VC++ 2008 compiler error: "CRT detected that the application wrote to the memory after end of heap buffer".
    ????
    thanks.

  13. #13
    Join Date
    Oct 2000
    Location
    London, England
    Posts
    4,773

    Re: operator overloading

    Problem of pointing it to "" is that your destructor is now trying to illegally delete it. Before when it was NULL it was ok to call delete on it, but you cannot call delete on the pointer here.

    You might solve the problem by having a flag. If it is non-empty then delete it. If it is empty then do not delete it. Ensure in your regular constructor that whenever the string passed in is an empty string it will set the flag. You also need to check this in assignment.

    Writing a well-written string class is much harder than it seems. The "standard library" does not even have a formal implementation, it just has a "pattern", i.e. how a string must behave, and it is up to the writers to implement this.

    operator= must return a reference. It is actually best implemented to do the following:
    - Separate implementations that take const char * and const string &
    - Check if the string will fit into the existing buffer and if so just copy it in.
    - If not, use (copy) constructor and swap rather than reallocate.

    The reason for having separate implementations for const char * and const string & is because if you use const string & all the time you will get implicit conversion which means you will often make more copies of the buffer than is necessary.

  14. #14
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: operator overloading

    What is operator+ supposed to do? Why work with a temporary char* when you can work with a temporary FunnyString that is returned? Have you considered implementing operator+=, then possibly implementing operator+ by using operator+=?

    EDIT:
    Quote Originally Posted by NMTop40
    Problem of pointing it to "" is that your destructor is now trying to illegally delete it. Before when it was NULL it was ok to call delete on it, but you cannot call delete on the pointer here.
    Sounds possible, but I cannot find where dakotabk made the mistake of setting the data member variable to anything other than the result of new[] or a null pointer constant.
    Last edited by laserlight; May 20th, 2009 at 05:08 AM.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  15. #15
    Join Date
    May 2009
    Posts
    5

    Re: operator overloading

    because there are also some operators (-,*,...), so it's not allow to change the FunnyString itself (There are only 2 FunnyString objects to implement, so if you change them, other operators can not begin correctly).
    The problem is, when an object contains pointer and destructor also ( destruct this pointer ), you can not return this object , don't you?

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured