Другие языки программирования и технологии

Вопрос по классам (и видимо по памяти) в С++

Короче вот в чем проблема... Есть класс mnogochlen. В нем существует параметр степени многочлена и массив коэффициентов float-ов (ибо коэффициенты не только целыми быть могут). Так... Требуется перегрузить оператор суммы "+" (сложение соответствующих коэффициентов). Помимо выше перечисленного в классе есть ряд методов (ввод, вывод на экран). Вот кусок класса:
class mnogochlen{
float* a; // Массив коэффициентов
unsigned short n; //степень многочлена
public:
mnogochlen operator + (mnogochlen M);
....
И так далее. Вот описание перегружаемого оператора:
mnogochlen mnogochlen::operator + (mnogochlen M){
mnogochlen temp;
delete temp.a;
....//Не важно, что написано в теле
temp.output(); //output() - метод класса, выводящий объект на экран
return temp;}
В теле данной ф-ии я создаю временный объект класса temp. Выделяю память под его динамический массив (предварительно очистив память, выделяющуюся конструктором по умолчанию). Само собой обнуляю все его элементы. Далее провожу различные махинации (не столь важно). Далее вывожу на экран этот временный объект. Вывод происходит, и он корректен. То есть, до оператора return все работает как надо. Как только доходит до return temp выскакивает ошибка. И, как бы я не объявлял сумму в теле main (C=A+B, A+B, (A+B).output()), выдается одна и та же ошибка. Может кто-нибудь сталкивался с подобным?
mnogochlen temp; - в этой строке создался некий temp, в котором есть a и n, причем a указывает непонятно куда (не установлен же) .
delete temp.a; - в этой строке мы освобождаем память, на которую указывает a, т. е. непонятно что.
Дальше - undefined behavior.
--
Все-таки temp.a установлен? Тогда это нарушение инкапсуляции.
А что после вызова функции? Точно ничего не происходит?
И вообще - гадать по куску кода неинтересно. Выкладывай все на pastebin.com, сюда - ссылку.
---
У меня после пары технических правок (как-никак, линукс) - все работает. Похоже, проблема в компиляторе.
--
Петр: да нет, ошибок там нет, код тупой, как пробка. Есть куча неэффективностей, и если он будет расти, по проблемы возникнут.. . но здесь их действительно не видно. Так что компилятор. IMHO.
---
Блин, дошло. Есть ошибка, и как раз из-за неправильной работы с памятью. Дело в том, что temp возвращается не ссылкой, а по значению, т. е. создается копия. При этом указатель a в копии равен ему же в temp. Затем вызывается temp.~mnogochlen, a освобождается, выводятся результаты.. . а потом вызывется деструктор копии и хочет удалить свой a. Что мы и наблюдаем.
Вот не надо пытаться перехитрить систему. Со своей памятью каждый объект должен работать сам, и не забываем конструктор копирования писать, если что-то выделяем отдельному объекту.
Макс Чирка
Макс Чирка
85 581
Лучший ответ
Ну ты хоть текст ошибки-то напиши, чай не телепаты тут сидят.
сраный мейлру не дает нормально ученикам редактировать ответы.
предыдущий коммент читать как "созданный (скопированный) объект ссылается на ту же область" -- скобка не там.

несколько придирок
у вас зря конструктор по умолчанию выделяет хоть какую то память.
семантически, дефолтный многочлен - это не многочлен степени ноль, а просто ноль.

бинарный оператор "+" по хорошему должен быть константным

там, где вы суммируете, у вас два куска одинакового кода в зависимости от того, степень какого многочлена выше - понятно что можно улучшить :)

использовать _getch из conio в смеси с cin/iostream только для того чтобы сделать паузу -- это ненужный изврат - читайте куда угодно из cin

ну итд
Андрей Лукин
Андрей Лукин
3 113
что значит " Как только доходит до return temp выскакивает ошибка"?
под дебаггером ошибка возникает непосредственно на return temp?
какая, кстати?

да и
----
mnogochlen temp;
delete temp.a;
-----
это какой то ад

автор - судя по коду, у вас там в деструкторе явно кака происходит
почему - хз, но, видимо, а указывает вникуда
не удаляйте вы память объекта снаружи него, объекты вам это не простят.
Aibolat *-*-*-*
Aibolat *-*-*-*
3 045
все понял
копирующий конструктор напишите, чтобы float* a копировал
иначе вы при выходе из функции уничтожаете temp, а его декструктор уничтожает а, а созданный (скопированный объект ссылается на ту же область)

как временную меру, чтобы проверить, можете закомментировать delete в деструкторе.