о деструкторах в с ++; - PullRequest
       9

о деструкторах в с ++;

2 голосов
/ 19 декабря 2011

я написал класс с именем octed_string, без деструктора он работает хорошо, но с этим он не мог вернуть в функцию никакой тип octed_string.

пожалуйста, посмотрите на код ниже и скажите мне, что не так.

когда я удаляю деструктор это работает! (принт 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 ]

11 голосов
/ 19 декабря 2011

Вам необходимо определить конструктор копирования и оператор присваивания для octed_string.

Когда у вас нет деструктора, он работает, потому что память, выделенная для переменной-члена value, не уничтожается икопия, созданная конструктором копирования по умолчанию, ссылается на ту же восстановленную память, что и оригинальный, теперь уничтоженный объект.

Если у вас есть деструктор, память удаляется.

Копия создается, когдаsub_string() возвращается.

1 голос
/ 19 декабря 2011

Чего ты пытаешься достичь? Это что-то, чего нельзя достичь с помощью 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;
}
1 голос
/ 19 декабря 2011

Возможные причины:

  • Опечатка: Вы объявили sub_string, но не sub_stirng.
  • Отсутствует реализация: ваша функция add() пуста
    • должен ли он что-то выделять?
  • У вас нет хорошо продуманной конструкции копирования и назначения копирования:
    • Когда ваш строковый объект копируется, одна из копий будет delete буфер значений
  • Отсутствует выделение вашего value буфера.
    • У вас нет выделенной памяти для вашего value -буфера вообще
  • прочее.

Лучший ответ на самом деле невозможен без действительного кода.

0 голосов
/ 29 ноября 2014

Любой класс, который имеет переменную-член типа указатель, нуждается в конструкторе копирования, перегруженном операторе = и деструкторе.

Рассмотрим следующий код:

octed_string str1; // suppose this is initialized as desired

octed_string str2 = str1; 

Во второй строке вызывается созданный компилятором конструктор копирования, который копирует элементы по одному. Здесь у нас есть элемент char_t * с именем value. Таким образом, значение str2 указывает на то же место в памяти str1. Это называется мелкой копией. В этом случае и str1, и str2 совместно используют одно и то же место в памяти для значения, что приведет к зависанию указателей, если str1 выйдет из области видимости. Следующий код показывает одну возможную ситуацию этого факта:

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

Та же история относится к назначению объектов.

...