简体   繁体   中英

about destructors in c++;

i wrote a class named octed_string , without a destructor it works well but with that it could not return any octed_string type in function.

please look at the code below and tell me what is wrong .

when i delete the destructor it work! (cout print 12)

can any one help?

class octed_string
{
private:
    uint8_t *value;
    size_t length;
    size_t allocated;
public:
    octed_string()//constructor
        :value(0),length(0),allocated(0)
    {

    }
    void copy(uint8_t *from, uint8_t *to)
    {
        for (size_t i = 0; i < length; i++)
            *to++ = *from++;
    }

    void allocate()
        {
            if (value == 0)
            {
                allocated = STACK_INITIAL_ALLOC;
                value = new uint8_t[allocated];
            }
            else
            {
                // We need to allocate more memory

                size_t new_allocated = allocated + STACK_CHUNK_ALLOC;
                uint8_t *new_value = new uint8_t[new_allocated];

                // Copy from old stack to new stack
                copy(value, new_value);

                // Delete the old value
                delete [] value;

                allocated = new_allocated;
                value = new_value;
            }
        }

    ~octed_string()//destructor
    {
        if(value)
            delete [] value;
    }

    friend ostream &operator<<(ostream &_output,const octed_string &_str)//opration overloading for cout
    {
        for(int i=0;i<_str.length;i++)
            _output<<(uchar_t)_str.value[i];
        return _output;
    }

    void add(uint8_t input)//this function automatically add space to value (new)
    {
        if (length == allocated)
            allocate();  // Allocate more memory

        value[length++] = _value;
    }

    octed_string sub_string(int start,int end)//( this function has a problem with destructor i think because it return octed_string)
    {
        octed_string a;
        for(int i=start;i<end;i++)
            a.add(a);
        return a;
    }
};

void main()
{
    octed_string o; //object
    o.add(1);
    o.add(2);
    o.add(3);

    cout<<o.sub_string(0,2); //i expect printing 12 but i does not!
}

-----------------------//answer thanks to phresnel it fix by adding following codes:

octed_string(const octed_string &_input)
    :value(0),length(0),allocated(0)
{
    while(length<_input.length)
    {
        this->add((uchar_t)_input[length]);
    }
}

octed_string& octed_string::operator= (octed_string const& _in)
{
    octed_string tmp(_in);
    return *this;
}

but i still can not understand the reason. could any body show any reference to learn this issue?

You need to define a copy constructor, and assignment operator, for octed_string .

When you do not have a destructor it works because the memory allocated for member variable value is not destroyed and the copy constructed by the default copy constructor refers to the same undeleted memory that original, now destroyed, object did.

When you do have a destructor the memory is deleted.

The copy is created when sub_string() returns.

Possible reasons:

  • Typo: You have declared sub_string , but not sub_stirng .
  • Missing implementation: Your add() function is empty
    • should it allocate something?
  • You do not have well designed copy construction and copy assignment:
    • When your string-object is copied around, one of the copies will delete the value buffer
  • Missing allocation of your value buffer.
    • You do not have allocated memory for your value -buffer at all
  • Other.

A better answer is not really possible without actual code.

What are you trying to achieve? Is it anything that cannot be achieved using std::string?

Couple of comments:

1 How are you newing value inside add?

2 prefix underscores (_output) area a bad idea

3 You need to define a copy constructor eg:

// Assuming value is an array
octed_string::octed_string( const octed_string& rhs) 
    : value( rhs.value ? new uint8_t[ rhs.length ] : 0 )
    , length( rhs.length )
    , allocated( rhs.allocated )
{
}

4 You also need an assignment operator

octed_string& octed_string::operator= (octed_string const& f)
{
    octed_string tmp( f );
    std::swap( tmp, *this );
    return *this;
}

Any class that has member variable of type pointer, needs a copy constructor, overloaded operator =, and destructor.

Consider the following code:

octed_string str1; // suppose this is initialized as desired

octed_string str2 = str1; 

At the second line, the compiler generated copy constructor is called, which copies the members one by one. Here we have a char_t* member named value. So, the value of str2 points to the same memory location of str1. This is called shallow copy. In this case, both str1 and str2 share the same memory location for value, which will cause dangling pointers if str1 goes out of scope. The following code shows one possible situation of this fact:

octed_string test() {
    octed_string str;
    // Initialize str...
    return str;
}

The same story applies to assignment of objects.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM