关于c ++中的析构函数;

时间:2011-12-19 11:28:59

标签: c++ destructor

我写了一个名为octed_string的类,没有析构函数它运行良好,但是它在函数中无法返回任何octed_string类型。

请查看下面的代码并告诉我出了什么问题。

当我删除析构函数时它工作! (cout print 12)

任何人都可以帮忙吗?

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!
}

----------------------- //答案 感谢phresnel它通过添加以下代码来解决:

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;
}

但我仍然无法理解原因。任何机构都可以参考这个问题吗?

4 个答案:

答案 0 :(得分:11)

您需要为octed_string定义复制构造函数和赋值运算符。

当你没有析构函数时,它可以正常工作,因为为成员变量value分配的内存不会被破坏,并且由默认复制构造函数构造的副本引用与原始(现在已销毁)对象相同的未删除内存

当你有一个析构函数时,内存将被删除。

sub_string()返回时创建副本。

答案 1 :(得分:1)

可能的原因:

  • 错字:您已宣布sub_string,但未宣布sub_stirng
  • 缺少实施:您的add()功能为空
    • 应该分配一些东西吗?
  • 您没有精心设计的副本构造和副本分配:
    • 复制字符串对象时,其中一个副本将delete值缓冲区
  • 缺少value缓冲区的分配。
    • 您根本没有为value - 缓冲区分配内存
  • 其他。

如果没有实际的代码,那么更好的答案是不可能的。

答案 2 :(得分:1)

你想要达到什么目的?是使用std :: string无法实现的吗?

几点意见:

1你如何在add中创造价值?

2前缀下划线(_output)区域是个坏主意

3您需要定义一个复制构造函数,例如:

// 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您还需要一个赋值运算符

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

答案 3 :(得分:0)

任何具有类型指针的成员变量的类,需要复制构造函数,重载operator =和析构函数。

请考虑以下代码:

octed_string str1; // suppose this is initialized as desired

octed_string str2 = str1; 

在第二行,调用编译器生成的复制构造函数,逐个复制成员。这里我们有一个名为value的char_t *成员。因此,str2的值指向str1的相同内存位置。这称为浅拷贝。在这种情况下,str1和str2共享值的相同内存位置,如果str1超出范围,将导致悬空指针。以下代码显示了这一事实的一种可能情况:

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

同样的故事适用于对象的分配。