Announcement

Collapse
No announcement yet.

[Help] Lỗi Hàm ~String Trong Lớp String

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • [Help] Lỗi Hàm ~String Trong Lớp String

    Mình đang Code bài tập về lớp chuỗi kí tự String. Debug bị lỗi fail assertion, trong khi mình Check lại không hề thấy lỗi, nhưng chạy lại lỗi. Mình kiểm tra hoài vẫn không thấy sai chỗ nào. Ngồi Check cả buổi rồi mình xóa hàm ~String luôn thì lại chạy bình thường.:shock:
    Vấn đề là mình muốn giữ hàm ~String thì phải làm cách nào. Các bạn xem giùm Code của mình có lỗi chỗ nào thì giúp mình hen.:go:

    Code :
    * File Header: STRING.h
    #pragma once
    #include "string.h"
    #include "iostream"
    using namespace std;

    class STRING
    {
    private:
    char *Content;
    int Lenght;
    public:
    STRING();
    STRING(char* s);
    STRING operator=(const STRING& p);
    ~STRING();
    friend STRING operator+(const STRING& p,const STRING& q);
    void Xuat();
    };
    *File Cpp: STRING.cpp
    #include "STRING.h"
    #include "string.h"
    #include "iostream"
    using namespace std;


    STRING::STRING()
    {
    Content=NULL;
    Lenght=0;
    }
    STRING::STRING(char* s)
    {
    Lenght=strlen(s);
    Content=new char [Lenght+1];
    strcpy(Content,s);
    }
    STRING STRING:perator=(const STRING& p)
    {
    delete []Content;
    Lenght=strlen(p.Content);
    Content=new char [Lenght+1];
    strcpy(Content,p.Content);
    return *this;
    }
    STRING::~STRING()
    {
    delete []Content;
    Lenght=0;
    }
    STRING operator+(const STRING& p,const STRING& q)
    {
    STRING t;
    t.Lenght=p.Lenght+q.Lenght;
    t.Content=new char [t.Lenght+1];
    strcpy(t.Content,p.Content);
    strcat(t.Content,q.Content);
    return t;


    }
    void STRING::Xuat()
    {
    cout<<Content<<"\n";
    }
    *File Cpp chứa hàm Main:
    #include "STRING.h"
    #include "string.h"
    #include "iostream"
    using namespace std;


    void main()
    {
    STRING x,y("DH CNTT"),z="DHQG";
    y.Xuat();
    z.Xuat();
    x=y+z;
    x.Xuat();


    }

  • #2
    có 2 cách:
    -thêm hàm tạo sao chép
    -xóa hàm hủy đi
    dĩ nhiên là nên chọn cách 1 =))

    Comment


    • #3
      dùng khai báo string tên biến đi khai báo char phức tạp

      Comment


      • #4
        Originally posted by 11520296 View Post
        dùng khai báo string tên biến đi khai báo char phức tạp
        nỡ đề yêu cầu xây dựng class string thì sao bác
        hàm hủy của bác em nghĩ viết thê này
        STRING::~STRING()
        {
        if(content!=NULL)
        {
        delete []Content;

        Lenght=0;
        }
        }
        hoặc
        STRING::~STRING(){}
        ko xóa đi như bác trên nói á!
        p/s: cho em hỏi khi thi có cần viết tách class,cpp,main ra ko hay viết chung cũng được ạ!:sweat:
        Last edited by 11520034; 25-12-2012, 23:08.
        Khi đã chọn công việc hay cái nghề cho mình thì nên đầu tư nhiều công sức cho nó thì sẽ thấy nó có nhiều cái hay để kiếm ra tiền lắm.Rồi cái quan trọng là có sức hay kiên trì mà làm không thôi! Đừng đứng núi này trông núi nọ thì phí hoài thời gian và tuổi trẻ thôi!

        Comment


        • #5
          Bài của bạn ban đầu cần thêm vào Copy Constructor là ok.

          Còn:
          Originally posted by 11520034 View Post
          nỡ đề yêu cầu xây dựng class string thì sao bác
          hàm hủy của bác em nghĩ viết thê này
          STRING::~STRING()
          {
          if(content=NULL)
          {
          delete []Content;

          Lenght=0;
          }
          }
          hoặc
          STRING::~STRING(){}
          ko xóa đi như bác trên nói á!
          PHP Code:
          STRING::~STRING()
          {
          if(
          content != NULL)
          {
          delete[] Content;
          Content NULL// tránh trường hợp con trỏ Content trỏ lung tung
          }
          Lenght 0;

          Vả lại, nên hủy bộ nhớ sau khi không dùng đến nó nữa. Sau này làm những Project lớn thì việc giải phóng bộ nhớ thật đáng được quan tâm.

          p/s: cho em hỏi khi thi có cần viết tách class,cpp,main ra ko hay viết chung cũng được ạ!:sweat:
          Cái này thì nên mỗi class là 1 cặp header + .cpp giúp project sáng sủa hơn.
          Last edited by 11520317; 25-12-2012, 19:18. Reason: Bổ sung
          Top Best Online - The Best Products Review Website

          Comment


          • #6
            Hình như các bạn chưa chạy thử source bạn #1 thì phải , bài bạn ấy ngay từ bước ~STRING đã lỗi rồi và còn nhiều chỗ khác nữa
            Code:
            STRING::~STRING()
            {
            delete []Content; [B][COLOR="#008000"]// chỗ này bạn nên để delete Content là được vì chỉ có 1 con trỏ kiểu STRING chứ không phải mảng [] con trỏ kiểu STRING[/COLOR][/B]
            Lenght=0;
            }
            }
            Mình sửa lại là
            Code:
            STRING::~STRING()
            {
            if(Content) delete Content; [COLOR="#008000"][B]// Nên cho 1 điều kiện if content # NULL thì mới giải phóng bộ nhớ , vì nếu ban đầu nó đã là NULL mà vẫn delete nữa thì sẽ lỗi , bạn có thể test[/B][/COLOR]
            Lenght=0;
            }
            Phương thức toán tử gán operator = , bạn để thêm cái tham chiếu "&" sau kiểu trả về của toán tử gán để nó trả thành phương thức tham chiếu
            Code:
            STRING& STRING::operator=(const STRING& p) [B][COLOR="#008000"]// bạn có thể test thử kết quả x=z có "&" và không "&"[/COLOR][/B]
            {
            delete []Content;
            Lenght=strlen(p.Content);
            Content=new char [Lenght+1];
            strcpy(Content,p.Content);
            return *this;
            }
            Cuối cùng là operator + , chỗ này thì bị lỗi về bộ nhớ rồi :sogood: giờ mình đi học nên tới đây thôi ... :sogood:

            Comment


            • #7
              Mình vẫn không hiểu nổi. Khi chạy đến operator+ vẫn tốt nhưng trước khi thoát khỏi operator+ lại đi vào hàm hủy và xóa luôn this thế là nó không trả về gì hết khi gọi x + y :--??
              not..

              Comment


              • #8
                Eh ông bạn đi học về thông não dùm nhe!!:kiss:

                Originally posted by 11520235 View Post
                Cuối cùng là operator + , chỗ này thì bị lỗi về bộ nhớ rồi :sogood: giờ mình đi học nên tới đây thôi ... :sogood:
                not..

                Comment


                • #9
                  /*chỗ này bạn chỉ cần nâng cấp co trỏ content lên là được*/
                  STRING operator+(const STRING& p,const STRING& q)
                  {
                  STRING *t=new STRING();
                  t->Lenght=p.Lenght+q.Lenght;
                  t->Content=new char [t->Lenght+1];
                  strcpy(t->Content,p.Content);
                  strcat(t->Content,q.Content);
                  return *t;
                  }
                  :happy: :smile:

                  Comment


                  • #10
                    Originally posted by 11520338 View Post
                    Mình vẫn không hiểu nổi. Khi chạy đến operator+ vẫn tốt nhưng trước khi thoát khỏi operator+ lại đi vào hàm hủy và xóa luôn this thế là nó không trả về gì hết khi gọi x + y :--??
                    Do chưa có Copy Constructor nên việc sao chép bị bỏ qua và vào thẳng hàm huỷ để huỷ biến tạm t.
                    Top Best Online - The Best Products Review Website

                    Comment


                    • #11
                      sai tè le hết, có muốn sửa cũng khó!
                      đây là bài của mình
                      Code:
                      #include<iostream>
                      #include<conio.h>
                      #include<string.h>
                      
                      using namespace std;
                      
                      class String
                      {
                      private:
                      	char *str;
                      
                      public:
                      	String(const char *s)
                      	{
                      		str=new char[strlen(s)+1];
                      		strcpy(str,s );
                      	}
                      
                      	String(const String &s)
                      	{		
                      		str=new char[strlen(s.str)+1];
                      		strcpy(str, s.str);
                      	}
                      
                      	~String(){ 
                      		if(str) 
                      			delete[] str; 
                      		str=NULL;
                      	}
                      
                      	const String &operator = (const String &s)
                      	{
                      		if(str)
                      			delete[] str;
                      		str=strdup(s.str);
                      		return *this;
                      	}
                      
                      	String operator + (const String &ss)
                      	{				
                      		char *temp1=strdup(str);		
                      		if(str)
                      			delete[] str;		
                      		str=strdup(strcat(temp1, ss.str));
                      		return *this;
                      	}
                      
                              friend ostream &operator << (ostream &out, const String &a)
                      	{
                      		out<<a.str<<endl; 
                      		return out;
                      	}
                      };
                      
                      void main()
                      {
                      	String a("em yeu truong em");
                      	String b("voi bao ban than");	
                      	
                      	a=a+b;
                      
                      	cout<<a<<b;
                      	getch();
                      }
                      Last edited by 11520327; 25-12-2012, 20:45.

                      Comment


                      • #12
                        đã sửa xong.
                        Code:
                        #include<iostream>
                        #include<conio.h>
                        
                        using namespace std;
                        
                        
                        class STRING
                        {
                        private:
                        	char *Content;
                        	int Lenght;
                        public:
                        	STRING();
                        	STRING(char* s);
                        	STRING(const STRING &a);
                        	STRING operator=(const STRING& p);
                        	~STRING();
                        	friend STRING operator+(const STRING& p,const STRING& q);
                        	void Xuat();
                        };
                        
                        STRING::STRING()
                        {
                        	Content=NULL;
                        	Lenght=0;
                        }
                        STRING::STRING(char* s)
                        {
                        	Lenght=strlen(s);
                        	Content=new char [Lenght+1];
                        	strcpy(Content,s);
                        }
                        STRING::STRING(const STRING &a)
                        {
                        	Content=new char[a.Lenght+1];
                        	strcpy(Content, a.Content);
                        }
                        STRING STRING::operator = (const STRING& p)
                        {
                        	if(Content)
                        		delete[]Content;
                        	Lenght=strlen(p.Content);
                        	Content=new char [Lenght+1];
                        	strcpy(Content,p.Content);
                        	return *this;
                        }
                        STRING::~STRING()
                        {
                        	delete []Content;
                        	Lenght=0;
                        }
                        STRING operator+(const STRING& p,const STRING& q)
                        {
                        	STRING t;
                        	t.Lenght=p.Lenght+q.Lenght;
                        	t.Content=new char [t.Lenght+1];
                        	strcpy(t.Content,p.Content);
                        	strcat(t.Content,q.Content);
                        	return t;
                        }
                        void STRING::Xuat()
                        {
                        	cout<<Content<<"\n";
                        }
                        
                        void main()
                        {
                        	STRING x,y("DH CNTT"),z=" DHQG";
                        	y.Xuat();
                        	z.Xuat();
                        	x= y+z;
                        	x.Xuat();
                        	getch();
                        }
                        thêm hàm khởi tạo sao chép copy. nhớ là nếu dùng cấp phát động thì phải viết hàm này.
                        Code:
                         STRING::STRING(const STRING &a)
                        {
                        	Content=new char[a.Lenght+1];
                        	strcpy(Content, a.Content);
                        }
                        sửa lại hàm toán tử gán bằng. bởi vì nếu Content chưa được khởi tạo mà gọi hàm delete sẽ lỗi nên phải kiểm tra trước.
                        Code:
                        STRING STRING::operator = (const STRING& p)
                        {
                        	if(Content)
                        		delete[]Content;
                        	Lenght=strlen(p.Content);
                        	Content=new char [Lenght+1];
                        	strcpy(Content,p.Content);
                        	return *this;
                        }
                        giải thích cái sửa thứ nhất:
                        khi trình biên dịch gặp câu lệnh return t trong hàm operator +,
                        trình biên dịch sẽ tạo ra 1 biến mới là bản sao của t( tạo bằng cách gọi hàm khởi tạo sao chép), biến mới là biến dùng để trả về( chú ý không phải là t nha).
                        do không có định nghĩa hàm này nên trình biên dịch sẽ gọi hàm khởi tạo sao chép ngầm định( hàm này sẽ sao chép từng bít từ vùng nhớ biến t sang biến mới),
                        do đó, con trỏ Content trong biến mới và con trỏ Content trong t trỏ đến cùng 1 vùng nhớ.
                        sau đó, hàm kết thúc, biến t là biến cục bộ nên sẽ gọi hàm hủy tương ứng, hàm này xóa luôn vùng nhớ chung của t và biến mới. do đó, vùng nhớ mà Content( biến mới) sẽ bị xóa.
                        hàm operator + trả về biến mới với thành phần Content "rỗng".

                        Comment


                        • #13
                          lúc gán cũng phải xóa hả Sang? mình cấp phát lại mà?

                          Comment


                          • #14
                            Đã "thông":brick:. Do quên mất bộ 3 xteen: khởi tạo, hủy, sao chép

                            Comment


                            • #15
                              Originally posted by 11520086 View Post
                              lúc gán cũng phải xóa hả Sang? mình cấp phát lại mà?
                              lúc gán ông xin cấp phát cái mới thì phải xóa cái cũ đi cho đỡ tốn bộ nhớ!

                              Comment

                              LHQC

                              Collapse
                              Working...
                              X