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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 06.10.2009, 04:09   #1
JOFRIF
Форумчанин
 
Регистрация: 21.04.2008
Сообщений: 164
По умолчанию Помгите найти ошибку (MV C++)

Помогите пожалуйста найти ошибку в коде.
Скорее всего дело в деструкторе или с удалением объектов...но я не уверен...
Внизу кода изображение ошибки.
код:
Код:
#include <iostream.h>
#include <string.h>

class Candybar
{
private:
	char *manufacturer_name;
	double weight;
	int calorie_content;
public:
	Candybar();
	Candybar(char *m_name,double wt,int cc);
	void print();
	~Candybar();
};
Candybar::Candybar(){};

Candybar::Candybar(char *m_name,double wt,int cc)
{
	manufacturer_name = new char[strlen(m_name)+1];
	strcpy(manufacturer_name,m_name);

	weight = wt;
	calorie_content = cc;
}

void Candybar::print()
{
	cout<<"The manufacturer name is: "<< manufacturer_name<<endl;
	cout<<"The weight is: "<<weight<<endl;
	cout<<"The calorie content is: "<<calorie_content<<endl;
}

Candybar::~Candybar()
{
	cout<<"Deliting manufacturer name "<<manufacturer_name<<endl;
	delete []manufacturer_name;
	cout<<"Manufacturer name has been deleted successfully               "<<manufacturer_name<<endl;
}

void main()
{
	Candybar snack[3];

	snack[0] = Candybar("Bounty",5.5,350);
	snack[0].print();
	
	snack[1] = Candybar("Snickers",4.5,450);
	snack[1].print();

	snack[2] = Candybar("Mars",3.5,550);
	snack[2].print();	
}
Изображения
Тип файла: jpg p.jpg (98.9 Кб, 134 просмотров)

Последний раз редактировалось JOFRIF; 06.10.2009 в 04:12.
JOFRIF вне форума Ответить с цитированием
Старый 06.10.2009, 11:15   #2
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

во-первых:
Код:
Candybar::~Candybar()
{
	cout<<"Deliting manufacturer name "<<manufacturer_name<<endl;
	delete []manufacturer_name;
	cout<<"Manufacturer name has been deleted successfully               "<<manufacturer_name<<endl;
}
кто тебе дал право использовать указатель после очистки памяти, на которую он указывает?

во-вторых:
Код:
Candybar snack[3];
snack[0] = Candybar("Bounty",5.5,350);
это называется конструктор копирования. твоя ошибка именно в этом. Ща объясню, что у тя тут происходит. ты имеешь 2 объекта класса Candybar (snack[0] и Candybar в правой части). т.е вызывается 2 конструктора, для левой части пустой, для правой части - с выделением памяти и копированием строки. НО! Когда срабатывает оператор =, по уполчанию он просто присваивает каждое значение из правой части значению в левой части! А у тебя там находится указатель. И получается так, что 2 указателя указывают на одну и ту же область памяти. Когда выполняется первый деструктор (какой - не важно), все норм. Но когда выполняется второй (а указатель на строку указывает на область памяти, которая удалена первым деструктором) - ошибка.
что делать? книги читать)
либо используй std::string, либо перегрузи оператор =, и точно так же выделяй память под свой указатель (но тут надо проверить, не выделил ли ты уже ее. если да - удалить, если нет - выделить) и копируй строку и 2 твоих значения.
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance

Последний раз редактировалось pproger; 06.10.2009 в 12:01.
pproger вне форума Ответить с цитированием
Старый 06.10.2009, 22:38   #3
JOFRIF
Форумчанин
 
Регистрация: 21.04.2008
Сообщений: 164
По умолчанию

Цитата:
кто тебе дал право использовать указатель после очистки памяти, на которую он указывает?
Но я же удаляю указатель delete []manufacturer_name;.
В книге написано что то вроде:"При первой возможности удаляйте/высвобождайте динамическую память чтобы иметь возможность использовать её заново ".Вот я и хотел ипользовать её заново.

Я не совсем понял что это за "конструктор копирования".
Объясните пожалуйста своими словами. Насколько я понял "конструктор копирования" это замысловатое название для обычного конструктора который инициализирует элементы. Поправте если я не прав.

Цитата:
Ща объясню, что у тя тут происходит. ты имеешь 2 объекта класса Candybar (snack[0] и Candybar в правой части).
3 объекта )

Цитата:
т.е вызывается 2 конструктора, для левой части пустой, для правой части - с выделением памяти и копированием строки.
Что это значит? Для какой левой части он пустой?
Возможно вы имели ввиду верхний и нижний(1-й и второй) конструкторы т.е( 1)Пустой конструктор 2)с параметрами )

Цитата:
И получается так, что 2 указателя указывают на одну и ту же область памяти.
хмм...Тогда, насколько я понял удаляется память на которую указывает указатель а не сам указатель.

Цитата:
что делать? книги читать)
Разумеется)

зы я не понимаю чем стринг может помочь...
JOFRIF вне форума Ответить с цитированием
Старый 06.10.2009, 22:51   #4
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

блин, я жопой чувствовал, что надо тебе семплы кидать было...

Цитата:
Но я же удаляю указатель delete []manufacturer_name;.
ты вообще посмотрел на сноску, которую я тебе дал?
Цитата:
cout<<"Deliting manufacturer name "<<manufacturer_name<<endl;
delete []manufacturer_name;
cout<<"Manufacturer name has been deleted successfully "<<manufacturer_name<<endl; - в этом месте указатель manufacturer уже удален! строчкой выше
Цитата:
В книге написано что то вроде:"При первой возможности удаляйте/высвобождайте динамическую память чтобы иметь возможность использовать её заново ".Вот я и хотел ипользовать её заново.[
чтобы потом опять сделать new и использовать ее, а не удалить и использовать недействительный указатель.

Цитата:
3 объекта )
нет, 2!
Цитата:
snack[0] = Candybar("Bounty",5.5,350);
тут используется !!!2!!! объекта класса Candybar, в левый и правый операнды.

на остальное мне сейчас влом отвечать. если желаешь, отпишись, утром с работы накидаю примеры
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance
pproger вне форума Ответить с цитированием
Старый 07.10.2009, 02:54   #5
JOFRIF
Форумчанин
 
Регистрация: 21.04.2008
Сообщений: 164
По умолчанию

Код:
ты вообще посмотрел на сноску, которую я тебе дал?
Цитата:cout<<"Deliting manufacturer name "<<manufacturer_name<<endl;
delete []manufacturer_name;
cout<<"Manufacturer name has been deleted successfully "<<manufacturer_name<<endl; - в этом месте указатель manufacturer уже удален! строчкой выше
Я думаю что не в этом ошибка, потому что я уже так делал для проверки(освободилась память или нет).
Если в строке
Код:
cout<<"Manufacturer name has been deleted successfully "<<manufacturer_name<<endl;
печаталось
Manufacturer name has been deleted successfully [][][][][][][]
то это означало что память освобожденна, а иначе нет.

Цитата:
чтобы потом опять сделать new и использовать ее, а не удалить и использовать недействительный указатель.
Как опять сделать new?! если этот new делается внутри коструктора??
Цитата:
Цитата:3 объекта )

нет, 2!
Цитата:snack[0] = Candybar("Bounty",5.5,350);

тут используется !!!2!!! объекта класса Candybar, в левый и правый операнды.
Я так понял что мы о разных объектах говорим. Я имел ввиду что три объекта это массив объектов snack[0]
snack[1]
snack[2]
А ты вообще говоришь про
snack[0] = Candybar("Bounty",5.5,350);
Только я не въехал с чего ты взял что Candybar("Bounty",5.5,350); это объект??? Это вообще конструктор а объектом является snack[0].

Цитата:
на остальное мне сейчас влом отвечать. если желаешь, отпишись, утром с работы накидаю примеры
Ок. Накидай.
JOFRIF вне форума Ответить с цитированием
Старый 07.10.2009, 08:14   #6
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Вместо того чтоб развозить демагогию просто нужно создавать обьекты динамически:
Код:
void main()
{
	Candybar* snack[3];

	snack[0] = new Candybar("Bounty",5.5,350);
	snack[0]->print();

	snack[1] = new Candybar("Snickers",4.5,450);
	snack[1]->print();

	snack[2] =new Candybar("Mars",3.5,550);
	snack[2]->print();

	delete[] snack;
cin.get();
}
Теперь понятно?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 07.10.2009, 12:13   #7
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

2Stilet
Цитата:
Вместо того чтоб развозить демагогию просто нужно создавать обьекты динамически:
это не дамагогия, а реальная проблема. естественно можно сделать через дин память, как ты показал, но раз человек сделал по другому, надо указать на его ошибки, а не навязывать свой вариант.

2JOFRIF
ты меня просто убил этой строкой:
Цитата:
cout<<"Manufacturer name has been deleted successfully "<<manufacturer_name<<endl;
Manufacturer name has been deleted successfully [][][][][][][]
то это означало что память освобожденна, а иначе нет.
ты вообще адекватен? НЕЛЬЗЯ ИСПОЛЬЗОВАТЬ УКАЗАТЕЛЬ СРАЗУ ПОСЛЕ ТОГО, КАК БЫЛ ПРИМЕНЕН delete! Он стал указывать на область памяти, которая под него не выделена!

Цитата:
А ты вообще говоришь про
snack[0] = Candybar("Bounty",5.5,350);
Только я не въехал с чего ты взял что Candybar("Bounty",5.5,350); это объект??? Это вообще конструктор
а что является результатом выполнения конструктора? в данном случае - временный объект, который удалится сразу после присваивания

вобщем, вот пример с перегрузкой оператора=
Код:
#include <iostream>
#include <string>

using namespace std;

class Candybar {
private:
	char *manufacturer_name;
	double weight;
	int calorie_content;
public:
	Candybar();
	Candybar(char *m_name,double wt,int cc);
	void operator=(const Candybar &obj);
	void print();
	~Candybar();
};

Candybar::Candybar() {

}

void Candybar::operator=(const Candybar &obj) {
	this->manufacturer_name = new char[strlen(obj.manufacturer_name)+1];
	strcpy(this->manufacturer_name, obj.manufacturer_name);
	this->weight = obj.weight;
	this->calorie_content = obj.calorie_content;
}

Candybar::Candybar(char *m_name,double wt,int cc) {
	manufacturer_name = new char[strlen(m_name)+1];
	strcpy(manufacturer_name,m_name);
	weight = wt;
	calorie_content = cc;
}

void Candybar::print() {
	cout<<"The manufacturer name is: " << manufacturer_name<<endl;
	cout<<"The weight is: " << weight << endl;
	cout<<"The calorie content is: " << calorie_content << endl;
}

Candybar::~Candybar() {
	cout << "Deliting manufacturer name " << manufacturer_name << endl;
	delete [] manufacturer_name;
	cout << "Manufacturer name has been deleted successfully" << endl;
}

void main() {
	Candybar snack[3];

	snack[0] = Candybar("Bounty",5.5,350);
	snack[0].print();

	snack[1] = Candybar("Snickers",4.5,450);
	snack[1].print();

	snack[2] = Candybar("Mars",3.5,550);
	snack[2].print();	
}
на остальные вопросы не хочу отвечать, ибо ты некомпетентен
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance

Последний раз редактировалось pproger; 07.10.2009 в 12:16.
pproger вне форума Ответить с цитированием
Старый 07.10.2009, 12:19   #8
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
а не навязывать свой вариант.
Но это ведь проще . Да и общепринято с обьектами работать через динамическую память все равно.
Впрочем автор пусть решает конечно же.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 08.10.2009, 03:28   #9
JOFRIF
Форумчанин
 
Регистрация: 21.04.2008
Сообщений: 164
По умолчанию

Всем спасибо, буду разбираться.
JOFRIF вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
помогите найти ошибку lg12 Помощь студентам 6 18.08.2009 18:26
найти ошибку rUs_LAN Общие вопросы C/C++ 8 14.05.2009 12:02
помогите найти ошибку! Picaso18 Паскаль, Turbo Pascal, PascalABC.NET 3 24.01.2009 15:32