Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 07.01.2013, 09:14   #1
Neverminded
 
Регистрация: 07.01.2013
Сообщений: 7
По умолчанию Выделение памяти. Ошибка.

Доброе утро! Есть программа, которая хранит сведения о студентах. В ней реализовано 2 класса. 1 - класс группа 2 - студент. не работает один метод - метод сортировки.
1. я создаю временный экземпляр класса "студент", в который перезаписываю экземпляр( в случае перестановки местами с экземпляром, у которого фио короче(ну в общем тот кто знает пузырьковую сортировку поймет))
В общем я отследил отладчиком что падает на этапе когда очищается память свойств экземпляра (я перегрузил опрератор "=" для экземпляров - падает именно в нем, т.е. когда я присваиваю)
Не очищается память - это значит одно - СКОРЕЕ ВСЕГО ОНА НЕ ПРАВИЛЬНО ВЫДЕЛЯЕТСЯ ИЗНАЧАЛЬНО! Но я проверял в других методах она очищается нормально а вот в методе сортировки не выходит. Помогите решить эту проблему.
Вот код:
я прокомментирую где именно она не работает:
Код:
    //class student
    
    
    void operator =(const Student& p) //ВОТ ПЕРЕГРУЗКА ОПЕРАТОРА ПРИСВАИВАНИЯ В КОТОРОМ СОБСТВЕННО 
    {                                             //И ПРОБЛЕМА
        if(name!=NULL)
            delete[] name;//  <- ВОТ В ЭТОЙ СТРОЧКЕ ПРОГРАММА ПАДАЕТ(Т.Е. КОГДА НАДО СТЕРЕТЬ ДАННЫЕ ИЗ 
        name=new char[strlen(p.name+1)];//ИЗ СВОЙСТВА HELLLPPP!!!
        strcpy(name,p.name);
 
        if(surname!=NULL)
        {
            delete[] surname;
        }
        surname=new char[strlen(p.surname+1)];
        strcpy(surname,p.surname);
 
        if(patronymic!=NULL)
        {
            delete[] patronymic;
        }
        patronymic=new char[strlen(p.patronymic+1)];
        strcpy(patronymic,p.patronymic);
        if(data.month!=NULL)
        {
            delete[]data.month;
        }
        data.month=new char[strlen(p.data.month+1)];
        strcpy(data.month,p.data.month);
        if(group!=NULL)
        {
 
            delete[]group;
        }
        group=new char[strlen(p.group+1)];
        strcpy(group,p.group);
 
        if(adress!=NULL)
        {
            delete[]adress;
        }
        adress=new char[strlen(p.adress+1)];
        strcpy(adress,p.adress);
 
        if(mail!=NULL)
        {
            delete[] mail;
        }
        mail=new char[strlen(p.mail+1)];
        strcpy(mail,p.mail);
        data.day=p.data.day;
        data.year=p.data.year;
        tell=p.tell;
        icq=p.icq;
    }
 
 
    
 
    bool operator <(const Student &p)//перегрузка операторов для сравнения ФИО
    {
        return ((comparison(p)<0)?true:false);
    }
 
    bool operator >(const Student &p)
    {
        return ((comparison(p)>0)?true:false);
    }
 }
   
};
//class Group
{

 
    void add(char* aname,char* asurname,char* apatronym,char* agrop,char* aadres,char* amail,int aday,char* amouth, //метод добавления студента в группу
        int ayear,int atell,int aicq)
    {
 
        size++;
        if(size<2)
        {
            _student=new Student [size];
 
 
            for(int i=0;i<size;i++)
            {
 
                _student[i].set_name(aname);
                _student[i].set_surname(asurname);
                _student[i].set_patr(apatronym);
                _student[i].set_gr(agrop);
                _student[i].set_adr(aadres);
                _student[i].set_mail(amail);
                _student[i].set_day(aday);
                _student[i].set_month(amouth);
                _student[i].set_year(ayear);
                _student[i].set_icq(aicq);
                _student[i].set_tell(atell);
            }
 
        }
 
 
        else if (size>1)
        {
            Student* mas=new Student[size];
            for(int i=0;i<size-1;i++)
            {
                mas[i]=_student[i];
            }
            mas[size-1].set_name(aname);
            mas[size-1].set_surname(asurname);
            mas[size-1].set_patr(apatronym);
            mas[size-1].data.day=aday;
            mas[size-1].set_month(amouth);
            mas[size-1].data.year=ayear;
            mas[size-1].set_gr(agrop);
            mas[size-1].set_adr(aadres);
            mas[size-1].set_mail(amail);
            mas[size-1].set_icq(aicq);
            mas[size-1].set_tell(atell);
            _student=new Student[size];
            for (int i=0;i<size;i++)
            {
                _student[i]=mas[i];
            }
 
 
        }
    }
   
 
    void sorting() // вот этот метод сортировки по фио
    {
        Student temp;
        for(int i = 1; i < size;i++)
        {
            for(int j = i; j < size; j++)
            {
                if(_student[i - 1] > _student[j])
                {
                    temp = _student[i - 1];
                    _student[i - 1] = _student[j]; // <- вот здесь падает когда 
                    _student[j] = temp;               // необходимо перезаписать 
                }//одно свойство в другое
            }
 
        }
    }
 
 
 
};

Последний раз редактировалось Stilet; 07.01.2013 в 13:57.
Neverminded вне форума Ответить с цитированием
Старый 07.01.2013, 09:42   #2
Son Of Pain
Участник клуба
 
Регистрация: 23.12.2010
Сообщений: 1,129
По умолчанию

1) Проверка указателя на null перед вызовом delete[] лишняя - она уже есть там внутри;
2) Ты неправильно считаешь размер выделяемой памяти, должно быть
Код:
name=new char[strlen(p.name)+1];
3) Ну а ошибка скорее всего в том, что ты не обнуляешь указатели в конструкторе класса. Компилятор не инициализирует их сам, и при первом присваивании вызывается delete[] для случайного значения, из-за чего все и валится.
Son Of Pain вне форума Ответить с цитированием
Старый 07.01.2013, 14:36   #3
denrubun
Пользователь
 
Регистрация: 24.12.2012
Сообщений: 82
По умолчанию

не совсем по сабжу, но:
if(size<2) - вероятно имеется ввиду if(size==1)
потом:
_student = new Student[size]; - теперь видно что массив не нужен

у вас же есть operator= !! зачем теперь писать так?
Код:
for(int i=0;i<size;i++)
            {
 
                _student[i].set_name(aname);
                _student[i].set_surname(asurname);
                _student[i].set_patr(apatronym);
                _student[i].set_gr(agrop);
                _student[i].set_adr(aadres);
                _student[i].set_mail(amail);
                _student[i].set_day(aday);
                _student[i].set_month(amouth);
                _student[i].set_year(ayear);
                _student[i].set_icq(aicq);
                _student[i].set_tell(atell);
            }
почему бы не сделать так вот:
_student[i] = Student(aname, asurname, ... ну дальше понятно

ну и последнее:
Код:
for(int i=0;i<size-1;i++)
{
      mas[i]=_student[i];
}
...
for (int i=0;i<size;i++)
{
       _student[i]=mas[i];
}
какие цели вы преследовали?
denrubun вне форума Ответить с цитированием
Старый 07.01.2013, 22:44   #4
Neverminded
 
Регистрация: 07.01.2013
Сообщений: 7
По умолчанию

Цитата:
Сообщение от denrubun Посмотреть сообщение
не совсем по сабжу, но:
if(size<2) - вероятно имеется ввиду if(size==1)
потом:
_student = new Student[size]; - теперь видно что массив не нужен

у вас же есть operator= !! зачем теперь писать так?
Код:
for(int i=0;i<size;i++)
            {
 
                _student[i].set_name(aname);
                _student[i].set_surname(asurname);
                _student[i].set_patr(apatronym);
                _student[i].set_gr(agrop);
                _student[i].set_adr(aadres);
                _student[i].set_mail(amail);
                _student[i].set_day(aday);
                _student[i].set_month(amouth);
                _student[i].set_year(ayear);
                _student[i].set_icq(aicq);
                _student[i].set_tell(atell);
            }
почему бы не сделать так вот:
_student[i] = Student(aname, asurname, ... ну дальше понятно

ну и последнее:
Код:
for(int i=0;i<size-1;i++)
{
      mas[i]=_student[i];
}
...
for (int i=0;i<size;i++)
{
       _student[i]=mas[i];
}
какие цели вы преследовали?
Я создаю временный массив, в который перезаписываю все предшествующие экземпляры "студентов" плюс добавляю в него последний экземпляр(это метод добавления экземпляров "студент"), а затем пересоздаю главный массив уже с новым размером (больше на 1) и записываю в него данные из временного массива.

Последний раз редактировалось Neverminded; 07.01.2013 в 22:49.
Neverminded вне форума Ответить с цитированием
Старый 07.01.2013, 23:23   #5
Neverminded
 
Регистрация: 07.01.2013
Сообщений: 7
По умолчанию

Цитата:
Сообщение от Son Of Pain Посмотреть сообщение
1) Проверка указателя на null перед вызовом delete[] лишняя - она уже есть там внутри;
2) Ты неправильно считаешь размер выделяемой памяти, должно быть
Код:
name=new char[strlen(p.name)+1];
3) Ну а ошибка скорее всего в том, что ты не обнуляешь указатели в конструкторе класса. Компилятор не инициализирует их сам, и при первом присваивании вызывается delete[] для случайного значения, из-за чего все и валится.
Спаcибо Вам огромное! Я просидел 4 дня и не смог увидеть! Всё работает, вопрос закрыт!
Neverminded вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
выделение памяти в Си Артэс Общие вопросы C/C++ 2 12.09.2012 10:57
Выделение памяти Blind Guard Общие вопросы C/C++ 22 06.06.2012 19:48
Распределение памяти. Динамическое выделение памяти с++ Tolian92 Помощь студентам 8 14.05.2012 21:44
Выделение памяти (new) ImmortalAlexSan Общие вопросы C/C++ 20 05.06.2011 23:39
Выделение памяти antoha.by Паскаль, Turbo Pascal, PascalABC.NET 2 29.04.2008 20:04