Документ взят из кэша поисковой машины. Адрес оригинального документа : http://www.mmonline.ru/forum/read/7/30513/
Дата изменения: Mon Apr 11 16:15:24 2016
Дата индексирования: Mon Apr 11 16:15:24 2016
Кодировка: Windows-1251
MMOnline | Форумы | Разное | Паранормальные проблемы со здачей зачета по ЭВМ

Паранормальные проблемы со здачей зачета по ЭВМ

Автор темы anime~ 
29.05.2003 20:05
anime~
Паранормальные проблемы со здачей зачета по ЭВМ
Народ, тут такое дело... Я в который раз уже имею паранормальные проблемы со здачей зачета по ЭВМ...Мне сказали приходить на коммисию, но если я принесу работающую программу, то поставят зачет.
У меня программа - реализация Нмерного вектора комплексных чисел.
Заведено два класса - класс векторов из комплексных чисел и, соответственно, класс комплексных чисел.
В деструкторе я пишу: free(a) , где а - это вектор комплексных чисел, то есть vector a, class vector {int N; complex *x;}
Так вот компилятору все время не нравится что то именно в вызове free(a). Я уже пытался заменять все маллоки на new, а все free на delete, но компилятор и даже дебаггер говорят то же самое.

ЕСТЬ ИДЕИ??? :(:(:(
29.05.2003 21:10
а подробнее?
Во-первых, НЕ НАДО НИКОГДА использовать в программе на C++ malloc/free потому, что не надо этого делать никогда.
Во-вторых, что именно не нравится компилятору? Какое сообщение выдается и на какую программную строку? Как определен соответствующий тип? Напишите, вероятнее всего, это прояснит дело.
В третьих, существует большая разница между new и new[]. Объекты, созданные оператором new, в большинстве реализаций можно более или менее безболезненно удалить с помощью free, но вот то, что создано new[], удалять по free нельзя ни в коем случае!!! В общем, строжайшим образом проверьте соответствие аллокаторов-деаллокаторов, используемых при создании и удалении объектов: malloc-free, new-delete, new[]-delete[]. Но такие ошибки обычно проявляются не при компиляции, а при запуске в виде SIGSEGV или же жестоких глюков.

Опять же, в деструкторе чего вы пишете free(a)? Если a - это class vector {int N; complex *x; } - тогда вообще смертельно, т.к. освобождать надо зааллоцированный в конструкторе x, а vector сам освободится, раз уж его деструктор вызвался. Такой деструктор приведет к попытке двойного освобождения памяти вашего класса из двух элементов и к утечке памяти из-под complex, т.к. ее в этом случае не освободит никто. IMHO, должно быть написано:

vector::vector (int NumberOfElements)
{
N = NumberOfElements;
x = new complex[N];
}

vector::~vector()
{
delete[] x;
}

У Вас не так?
29.05.2003 21:24
Книжка
Если мне не изменяет память, то в книжке "ООП с использованием C++" (Ире Пол) приведен код (да еще и с комментариями) того, что тебе надо.
Удачи!!!
29.05.2003 22:39
anime~
гм.
Боюсь вываливать сюда всю программу :) она конечно здоровенная для форума...может я Вам пришю по почте?
Вот кусок из нее:

class vector
{



int N;
complex *x;

public:


vector (int n=0, complex *xn=NULL)
{
N = n;
x = xn;
}

vector (const vector &ha)
{
int yo = 0;
this->N = ha.N;
//this->x =(complex*)malloc(N*sizeof(complex));
x = new complex[N];
for(yo=0; yo<N; yo++)
{this->x[yo]=ha.x[yo];};
}

~vector()
{

N=0;

// Free Tibet

delete [] x;

}
29.05.2003 22:54
Как надо делать
Во-первых, _н_е_л_ь_з_я_ использвовать malloc/free, ибо они просто выделяют память под указанный тип, а у обьекта еще есть как минимум конструктор, да и структра у него может быть очень разветвленной, которую и инициализирует new.

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

Конструктор:

int i;
complex **arrX; // Массив динамических обьектов

arrX = (malloc**)(N*sizeof(complex*));

for(i=0;i<N;i++) {
arrX = new complex;
}

Деструктор:

int i;

for(i=0;i<N;i++) {
delete arrX;
}

free(arrX);


(К сожалению, я плохо знаю C++, предпочитаю простой C, так что это только идея, может не совсем идеально работать)
30.05.2003 02:27
Не надо так делать
Цитата

Во-вторых, ты неправильно понял назначение квадратных скобочек у оператора new. Они не заводят массив, они указывают значение, которым надо инициализировать твой обьект.
Как говорится -- не знаете, не надо советовать. Конструкция new T[n] выделяет именно массив из n элементов типа (класса) T. Для созданных экземпляров вызывается default constructor. Советую прочитать п. 5.3.4/14 Стандарта.

Цитата

По-хорошему, надо делать все примерно так:
Заводить массив указателей на объекты не по делу, да кроме того смешивать в коде malloc/free с new/delete -- очень странный стиль.

Цитата

(К сожалению, я плохо знаю C++, предпочитаю простой C, так что это только идея, может не совсем идеально работать)
Заметно.

30.05.2003 06:51
Red
Если хочешь, шли код, разберемся
30.05.2003 12:11
anime~
очень даже хочу
30.05.2003 14:33
F1
первое, что бросается в глаза...
Ваш конструктор может "создать" объект, не проинициализировав (если Вы создадите его без параметров), а деструктор потом попытается удалить то, что никогда не создавалось (вызвав delete[] от NULL).
В общем, если Вам еще не помогли прояснить ситуацию, пошлите программу на rugpc-2l@nm.ru, помогу.
30.05.2003 15:51
anime~
я уже отослал
я уже послал программу Red'у, но и Вам пошлю, мне хуже не будет :В :)
30.05.2003 22:22
anime~
спасибо
Я получил письма от Red и F1, оба говорят умные вещи, в которые хочется верить, причем одинаковые :) К сожалению, сейчас я не могу перекомпилировать программу, чтобы во всем самому убедиться, но сделаю это очень скоро.
Большое спасибо за помощь.
Извините, только зарегистрированные пользователи могут публиковать сообщения в этом форуме.

Кликните здесь, чтобы войти