Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RFpro.ru: Программирование на C / C++


Хостинг портала RFpro.ru:
Московский хостер
Профессиональный ХОСТИНГ на базе Linux x64 и Windows x64

РАССЫЛКИ ПОРТАЛА RFPRO.RU

Лучшие эксперты данной рассылки

Асмик Александровна
Статус: Академик
Рейтинг: 8279
∙ повысить рейтинг »
Boriss
Статус: Академик
Рейтинг: 2673
∙ повысить рейтинг »
Коцюрбенко Алексей aka Жерар
Статус: Профессор
Рейтинг: 2483
∙ повысить рейтинг »

/ КОМПЬЮТЕРЫ И СОФТ / Программирование / C/C++

Номер выпуска:1676
Дата выхода:12.06.2011, 13:00
Администратор рассылки:Киселёва Алёна aka Verena (Профессор)
Подписчиков / экспертов:300 / 178
Вопросов / ответов:1 / 1

Вопрос № 183535: Здравствуйте! У меня возникли сложности с таким вопросом: Опять я со своими баранами. Вот код проекта: исходники Пере...



Вопрос № 183535:

Здравствуйте! У меня возникли сложности с таким вопросом:

Опять я со своими баранами. Вот код проекта: исходники
Перегруженные операции для класса все работают, но работают по одиночке, если проводить несколько подряд операций - программа вылетает без сообщений об ошибке.

Код :
#include
"baseset.h"

int main()
{
  int arr[] = {1,2,3,4,5,6,7,8,9};
  BaseSet bset(arr, 9);
  BaseSet bset2(bset);  

  bset.Print();
  bset2.Print();

  //Проверка операции деления
  BaseSet bset3 = bset/bset2;
  bset3.Print();

  //Проверка операции вычитания
  bset3 = bset - bset2;
  bset3.Print();
  
  //До сюда всё работает. Дальше - фиг
  //Проверка операции умножения
  bset3 = bset - bset2;
  bset3.Print();
  
  //Проверка операции сложения
//  bset3 = bset + bset2;
//  bset3.Print();

  return 0;
}

Помогите разобраться...

Отправлен: 07.06.2011, 12:32
Вопрос задал: sir Henry (Старший модератор)
Всего ответов: 1
Страница вопроса »


Отвечает Micren (Профессор) :
Здравствуйте, sir Henry!
Ошибка в конструкторе BaseSet(int *pIntArray, unsigned int len)
Вы не клонируете данные, а просто присваиваете указатель на данные. Которые, кстати, являются автоматической переменной. Т.е. данные не выделяются динамически. Соответственно, деструктор при попытке удалить их вылетает.
Код :
#include "baseset.h"

int main()
{
  int arr[] = {1,2,3,4,5,6,7,8,9};
  BaseSet bset(arr, 9);
  BaseSet bset2(bset);

  bset.Print();
  bset2.Print();

  //Проверка операции деления
  BaseSet bset3 = bset/bset2;
  bset3.Print();


  //Проверка операции вычитания
  bset3 = bset - bset2;
  bset3.Print();

  //Проверка операции умножения
  bset3 = bset - bset2;
  bset3.Print();

  //Проверка операции сложения
//  bset3 = bset + bset2;
//  bset3.Print();

  return 0;
}

Код :
//baseset.h
//базовый класс - Множество
#ifndef BASESET_H
#define DASESET_H

#include <stdlib.h>
#include <iostream>

using namespace std;

//Класс - Множество

class BaseSet
{
protected:
    int* Array; //Массив хранения значений множества
    unsigned int Count; //Количество хранящихся в массиве значений

    //Удаление массива хранения

    void Destroy()
    {
        if (Array)
        {
            delete [] Array;
            Array = NULL;
            Count = 0;
        }
    }

    //Копирование значений из другого массива

    void Copy(int *pIntArray, unsigned int len)
    {
        if (pIntArray)
        {
            Destroy();
            Array = new int[len];
            for (size_t i = 0; i < len; ++i)
            {
                Array[i] = pIntArray[i];
            }
            Count = len;
        }
    }
public:

    //Конструкторы. Без параметров

    BaseSet() : Array(0), Count(0)
    {
    }

    //С созданием пустого множества
    //Параметры:
    //len - количество ячеек хранения

    BaseSet(unsigned int len) : Array(0), Count(len)
    {
        Array = new int[Count];
        for (unsigned int i = 0; i < Count; i++)
        {
            Array[i] = 0;
        }
    }

    //С передачей указателя на целочисленный массив
    //Параметры:
    //*pIntArray - указатель на массив
    //len - количество элементов в массиве

    BaseSet(int *pIntArray, unsigned int len) : Array(0), Count(0)
    {
        if (pIntArray != NULL)
        {
            Copy(pIntArray, len);
        }
        else
        {
            cout << "Множество не создано. Видимо это пустой массив..." << endl;
        }
    }

    //Конструктор копирования
    //Параметры:
    //Other - другой объект, из которого надо скопировать значения

    BaseSet(const BaseSet& Other) : Array(0), Count(0)
    {
        Copy(Other.Array, Other.GetCount());
    }

    //Деструктор

    ~BaseSet()
    {
        Destroy();
    }

    //Получить количество ячеек хранения

    unsigned int GetCount() const
    {
        return Count;
    }

    //Вывод значений множества на экран по горизонтали

    void Print()
    {
        for (unsigned int i = 0; i < Count; i++)
        {
            cout << Array[i] << " ";
        }
        cout << endl;
    }

    //Перегрузка операций
    //Индексация

    int &operator[] (unsigned int Index) const
    {
        if (Index >= (Count))
        {
            cout << "Индекс " << Index << " больше, чем количество данных..." << endl;
            exit(1);
        }
        return Array[Index];
    }

    //Присваивание

    BaseSet & operator=(const BaseSet& Other)
    {
        if (this != &Other)
        {
            Copy(Other.Array, Other.Count);
        }
        return *this;
    }

    //Сложение

    BaseSet operator+(const BaseSet& Other) const
    {
        unsigned int cnt = min(Count, Other.Count);
        BaseSet result(cnt);
        for (unsigned int i = 0; i < cnt; i++)
        {
            result.Array[i] = Array[i] + Other.Array[i];
        }
        return result;
    }

    //Вычитание

    BaseSet operator-(const BaseSet& Other) const
    {
        unsigned int cnt = min(Count, Other.Count);
        BaseSet result(cnt);
        for (unsigned int i = 0; i < cnt; i++)
        {
            result.Array[i] = Array[i] - Other.Array[i];
        }
        return result;
    }

    //Умножение

    BaseSet operator*(const BaseSet& Other) const
    {
        unsigned int cnt = min(Count, Other.Count);
        BaseSet result(cnt);
        for (unsigned int i = 0; i < cnt; i++)
        {
            result.Array[i] = Array[i] * Other.Array[i];
        }
        return result;
    }

    //Деление

    BaseSet operator/(const BaseSet& Other) const
    {
        unsigned int cnt = min(Count, Other.Count);
        BaseSet result(cnt);
        div_t x;
        for (unsigned int i = 0; i < cnt; i++)
        {
            x = div(Array[i], Other.Array[i]);
            result.Array[i] = x.quot;
        }
        return result;
    }
};
#endif

Ответ отправил: Micren (Профессор)
Ответ отправлен: 07.06.2011, 13:03
Номер ответа: 267611
Украина, Краматорск

Оценка ответа: 5
Комментарий к оценке:
Как всегда - отлично!

Вам помог ответ? Пожалуйста, поблагодарите эксперта за это!
Как сказать этому эксперту "спасибо"?
  • Отправить SMS #thank 267611 на номер 1151 (Россия) | Еще номера »
  • Отправить WebMoney:


  • Оценить выпуск »
    Нам очень важно Ваше мнение об этом выпуске рассылки!

    Задать вопрос экспертам этой рассылки »

    Скажите "спасибо" эксперту, который помог Вам!

    Отправьте СМС-сообщение с тестом #thank НОМЕР_ОТВЕТА
    на короткий номер 1151 (Россия)

    Номер ответа и конкретный текст СМС указан внизу каждого ответа.

    Полный список номеров »

    * Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи. (полный список тарифов)
    ** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются.
    *** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании.



    В избранное