Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

С++

55K
03 марта 2011 года
g00dv1n
22 / / 28.11.2010
Делаю курсовую.
Вот придумал класс Box и хочу запихивать в него объекты своего класса Tomato.
Но какието проблемы с памятью..

Код:
#pragma once
#include <string.h>
#include "Tomato.h"
#include <list>
//const int Max=30;

using namespace std;

typedef list<Tomato> Tlist;

class Box
{
private:
    int Capacity;
    char *Material;
    Tlist box;
public:

    Box(): Capacity(0)
    {
        Material=new char [strlen("unknow")+1];
        strcpy(Material,"unknow");
    }

    ~Box()
    {
        delete Material;
    }
    int SetMaterial(char *material);
    char *GetMaterial();
    void AddTomato(const Tomato &object);
};

int Box::SetMaterial(char *material){
    Material=new char [strlen(material)+1];
    strcpy(Material,material);
    return 1;
}

char *Box::GetMaterial(){
    return Material;
   
}

void Box::AddTomato(const Tomato &object){
    box.push_back(object);
    Capacity++;
}
278
03 марта 2011 года
Alexander92
1.1K / / 04.08.2008
1.
 
Код:
Box(): Capacity(0)
    {
        Material = new char[strlen("unknow")+1];
        strcpy(Material,"unknow");
        box.resize(0);
    }


2. Material - это строка, поэтому не
[QUOTE=g00dv1n]
 
Код:
~Box()
    {
        delete Material;
    }

[/QUOTE]
, а
 
Код:
~Box()
    {
        delete[] Material;
    }


3.
[QUOTE=g00dv1n]
 
Код:
int Box::SetMaterial(char *material){
    Material=new char [strlen(material)+1];
    strcpy(Material,material);
    return 1;
}

[/QUOTE]
На каком основании при каждой установке материала вы выделяете заново память под Material? Вы уже выделили ее один раз в конструкторе, в дальнейшем - юзайте функции в стиле realloc().

4. Маленькое замечание: раз уже пишете целиком на плюсах, то используйте std::string вместо char*, оно и попроще выйдет.
360
03 марта 2011 года
P*t*
474 / / 15.02.2007
Какие проблемы с памятью? Утечка памяти? Или, может быть, double free?

Пока вижу одну ошибку:
В Box::SetMaterial(char *material)
Перед Material=new char [strlen(material)+1];
нужно вставить delete Material;

З.Ы
Ну блин, опять опоздал :(

2 Alexander92
Экспериментально выяснено, что в большинстве случаев delete вместо delete [] тоже работает. То есть я долгое время про delete [] не знал вообще, пока случайно не столкнулся с ошибками при удалении многомерного динамического массива. Теперь мне интересно, какая между ними разница в реализации?
55K
03 марта 2011 года
g00dv1n
22 / / 28.11.2010
Все исправил , но все равно..
вот скрин ошибки
278
03 марта 2011 года
Alexander92
1.1K / / 04.08.2008
Цитата: P*t*

2 Alexander92
Экспериментально выяснено, что в большинстве случаев delete вместо delete [] тоже работает. То есть я долгое время про delete [] не знал вообще, пока случайно не столкнулся с ошибками при удалении многомерного динамического массива. Теперь мне интересно, какая между ними разница в реализации?



Да, это я знаю, но я предпочитаю не дергать дедушку Страуструпа за бороду и делать, как он просит. :)

2 g00dv1n: во-первых, приведите код, как вы используете этот класс, во-вторых - запустите приложение в режиме отладки и посмотрите, на какой строке конкретно оно вылетает.

55K
03 марта 2011 года
g00dv1n
22 / / 28.11.2010
я знаю где конкретно вылетает на

 
Код:
Box box1;
Tomato b1;
box1.AddTomato(b1); // ВЫЛЕТАЕТ КОНКРЕТНО НА ЭТОЙ
278
03 марта 2011 года
Alexander92
1.1K / / 04.08.2008
Выкладывайте полный код, вместе с Tomato.h, будем смотреть.
392
03 марта 2011 года
cronya
421 / / 03.01.2009
 
Код:
box.push_back(object);

Смотрите эту фунцию, а именно ищем ошибку в 52 строке:

У меня ваще ощущение, что параметр неправильно передается в этой функции, увы без кода точно не скажешь!

 
Код:
AddTomato(const Tomato &object)
278
03 марта 2011 года
Alexander92
1.1K / / 04.08.2008
Цитата: cronya
 
Код:
box.push_back(object);

Смотрите эту фунцию, а именно ищем ошибку в 52 строке:

У меня ваще ощущение, что параметр неправильно передается в этой функции, увы без кода точно не скажешь!

 
Код:
AddTomato(const Tomato &object)



У меня ощущение, что там либо объект портится, либо в самом Tomato что-то не так. Опять же, нужен код.

55K
04 марта 2011 года
g00dv1n
22 / / 28.11.2010
Вот Tomato
Код:
#pragma once
#include "vegetable.h"
#include <string.h>
class Tomato :
    public Vegetable
{
private:
    char *Type;
    char *Size;
    char *Color;
    static unsigned int tomato_count;
public:

    Tomato(){
        Mass=0;
        Ripeness=0;
        Type=new char [strlen("unknown")+1];
        //Type=new char [11];
        strcpy(Type,"unknown");
        Size=new char [strlen("unknown")+1];
        //Size=new char [11];
        strcpy(Size,"unknown");
        Color=new char [strlen("unknown")+1];
        //Color=new char [11];
        strcpy(Color,"unknown");
        tomato_count++;
        count--;
    }
    Tomato(float mass, int ripeness, char *type, char *size, char *color)
    {
        Type=new char [strlen(type)+1];
        strcpy(Type,type);
        Size=new char [strlen(size)+1];
        strcpy(Size,size);
        Color=new char [strlen(color)+1];
        strcpy(Color,color);
        Mass=mass;
        Ripeness=ripeness;
        count--;
        tomato_count++;
    }

    ~Tomato(void)
    {
        delete [] Type;
        delete [] Size;
        delete [] Color;
        tomato_count--;
    }
    int SetType(char* type);
    char *GetType();
    int SetSize(char* size);
    char *GetSize();
    int SetColor(char* color);
    char *GetColor();
    unsigned int GetTomato_count();
    Tomato& operator -(Tomato &object);
    Tomato& operator =(const Tomato &object);
};

Tomato &Tomato::operator-(Tomato &object){
    if(Mass>object.Mass){
        return *this;
    }
    else {
        return object;
    }
}

Tomato& Tomato::operator=(const Tomato &object){
    if(this == &object)
        return *this;
    delete[] Type;
    Type=new char [strlen(object.Type)+1];
    strcpy(Type,object.Type);
    delete[] Color;
    Color=new char [strlen(object.Color)+1];
    strcpy(Color,object.Color);
    delete[] Size;
    Size=new char [strlen(object.Size)+1];
    strcpy(Size,object.Size);
    Mass=object.Mass;
    Ripeness=object.Ripeness;
    return *this;
}

unsigned int Tomato::tomato_count=0;

unsigned int Tomato::GetTomato_count(){
    return tomato_count;
}

int Tomato::SetType(char *type){
    delete [] Type;
    Type=new char [strlen(type)+1];
    strcpy(Type,type);
    return 1;
}

int Tomato::SetColor(char *color){
    delete [] Type;
    Color=new char [strlen(color)+1];
    strcpy(Color,color);
    return 1;
}

int Tomato::SetSize(char *size){
    delete [] Size;
    Size=new char [strlen(size)+1];
    strcpy(Size,size);
    return 1;
}

char * Tomato::GetColor(){
    return Color;
}

char * Tomato::GetSize(){
    return Size;
}

char * Tomato::GetType(){
    return Type;
}


А вот базовый класс

Код:
#pragma once
// Базовый класс овощи
class Vegetable
{  
protected:
    float Mass;
    int  Ripeness;
    static unsigned int count;
public:
    Vegetable(): Mass(0), Ripeness(0)
    {
        count++;
    }
    Vegetable(float mass, int ripeness): Mass(mass), Ripeness(ripeness)
    {
        count++;
    }

    ~Vegetable(void)
    {
        count--;
    }
    unsigned int GetCount();
    float GetMass();
    int SetMass(float mass);
    int GetRipeness();
    int SetRipeness(int ripeness);
    void Fertilize();
    Vegetable operator ++();
    Vegetable operator --();

};

unsigned int Vegetable::count=0;

unsigned int Vegetable::GetCount(){
    return count;
}


Vegetable Vegetable::operator++(){
    return Vegetable(Mass,++Ripeness);
}

Vegetable Vegetable::operator--(){
    return Vegetable(Mass,--Ripeness);
}

float Vegetable::GetMass(){
    return Mass;
}

int Vegetable::SetMass(float mass){
    if(mass>0){
        Mass=mass;
        return 1;
    }
    else
        return 0;
}


int Vegetable::GetRipeness(){
    return Ripeness;
}

int Vegetable::SetRipeness(int ripeness){
    if(ripeness>0){
        Ripeness=ripeness;
        return 1;
    }
    else
        return 0;
}

void Vegetable::Fertilize(){
    Mass+=0.1;
}
535
04 марта 2011 года
Нездешний
537 / / 17.01.2008
Напишите конструктор копий для Tomato. При выполнении Box.push_back(TomatoObject) происходит копирование объекта. Раз конструктор копий не определен, объект копируется побайтно (указатели тоже) - соответственно память внутри него под строки не выделяется.

ЗЫ
Зачем Capacity в Box? Есть же std::list::size()
55K
05 марта 2011 года
g00dv1n
22 / / 28.11.2010
Все написал конуструктор копирования и проблема решилась.
Благодарю за помощь на данном форуме.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог