Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > Проблема с деструктором


Автор: htzg 8.9.2010, 18:39
Народ! Есть проблема!
Создал класс. Компилятор его проглатывает. Но! Что то не то с деструктором. При запуске программа останавливается и выдается след. сообщение:

"Unhandled exception at 0x77b21fe0 in Prop-test1.exe: 0xC0000005: Access violation reading location 0x0000ffff"

Курсором указывает на
Код

delete [] Values[i][j] ;


Помогите разобраться! smile

Код

#include "stdafx.h"
#include <iostream>
#include <vector>

class CProp
{
    public:
        int NDIVIX,NDIVIY,NDIVIZ;
        float ***Values ;
        void Set(int ndiviX, int ndiviY, int ndiviZ)
        {
            ///----------Prop      -------------------
            Values = new float**[ndiviX];
            for(int i=0 ; i < ndiviX; ++i)
            {
                Values[i] = new float*[ndiviY];
                for(int j=0 ; j < ndiviY ; ++j)
                    Values[i][j] = new float[ndiviZ];
            }
            ///---------------------------------------
            ///
            ///------------Prop  inputing-------------
            for(int k=0 ; k < ndiviZ ; ++k)
                for(int j=0 ; j < ndiviY ; ++j)
                    for(int i=0 ; i < ndiviX ; ++i)
                        Values[i][j][k] = 1.0 ;
            ///---------------------------------------
            NDIVIX=ndiviX;
            NDIVIY=ndiviY;
            NDIVIZ=ndiviZ;
        }
        ~CProp();
};

CProp::~CProp()
{
    ///------------Prop destruction-----------
    for(int i=0 ; i < NDIVIX; ++i)
    {
        for(int j=0 ; j < NDIVIY; ++j)
        {
            delete [] Values[i][j] ;
        }
        delete  Values[i] ;
    }
    delete [] Values ;
    ///---------------------------------------
}

int _tmain(int argc, _TCHAR* argv[])
{
    std::vector<CProp> vProp;
    for(int i=0;i<3;++i)
    {
        CProp Prop;
        Prop.Set(10,20,5);
        vProp.push_back(Prop);
    }
    
    char ch;
    std::cin >> ch;

    return 0;
}


Автор: icecrashldr 8.9.2010, 18:55
Код

 for(int i=0 ; i < NDIVIX; ++i)
    {
        for(int j=0 ; j < NDIVIY; ++j)
        {
            delete Values[i][j] ;
        }
        delete  []  Values[i] ;
    }
    delete [] Values ;

Автор: Sartorius 8.9.2010, 18:56
push_back на сколько я помню конструктор копирования вызывает, которого у тебя нет. Получаем неинициализированне объекты в векторе

Автор: htzg 8.9.2010, 19:18
не подскажите как правильно конструктор копирования в моем случае создать...?
Я создаю, та же ошибка
Код

CProp::CProp(const CProp& CPr)
{
    NDIVIX = CPr.NDIVIX;
    NDIVIY = CPr.NDIVIY;
    NDIVIZ = CPr.NDIVIZ;
    Values = CPr.Values;
}

Автор: Sartorius 8.9.2010, 19:58
 Так дефолтный делает - копирует поля. Нужно создать массив с такими же размерностями как исходного объекта ( можешь Set вызвать) и скопировать все значения. 

Автор: htzg 8.9.2010, 20:06
Спасибо большое! Сработало! smile

Добавлено через 2 минуты и 45 секунд
Выкладываю окончательный вариант
Код

#include "stdafx.h"
#include <iostream>
#include <vector>

class CProp
{
    public:
        int NDIVIX,NDIVIY,NDIVIZ;
        float ***Values ;
        void Set(int ndiviX, int ndiviY, int ndiviZ)
        {
            ///----------Prop      -------------------
            Values = new float**[ndiviX];
            for(int i=0 ; i < ndiviX; ++i)
            {
                Values[i] = new float*[ndiviY];
                for(int j=0 ; j < ndiviY ; ++j)
                    Values[i][j] = new float[ndiviZ];
            }
            ///---------------------------------------
            ///
            ///------------Prop  inputing-------------
            for(int k=0 ; k < ndiviZ ; ++k)
                for(int j=0 ; j < ndiviY ; ++j)
                    for(int i=0 ; i < ndiviX ; ++i)
                        Values[i][j][k] = 1.0 ;
            ///---------------------------------------
            NDIVIX=ndiviX;
            NDIVIY=ndiviY;
            NDIVIZ=ndiviZ;
        }
        ~CProp();
        CProp(){};
        CProp(const CProp& );
};

CProp::CProp(const CProp& CPr)
{
    NDIVIX = CPr.NDIVIX;
    NDIVIY = CPr.NDIVIY;
    NDIVIZ = CPr.NDIVIZ;
    Values = new float**[NDIVIX];
    for(int i=0 ; i < NDIVIX; ++i)
    {
        Values[i] = new float*[NDIVIY];
        for(int j=0 ; j < NDIVIY ; ++j)
            Values[i][j] = new float[NDIVIZ];
    }
    for(int k=0 ; k < NDIVIX ; ++k)
        for(int j=0 ; j < NDIVIY ; ++j)
            for(int i=0 ; i < NDIVIZ ; ++i)
                Values[i][j][k] = CPr.Values[i][j][k] ;
}

CProp::~CProp()
{
    ///------------Prop destruction-----------
    for(int i=0 ; i < NDIVIX; ++i)
    {
        for(int j=0 ; j < NDIVIY; ++j)
        {
            delete [] Values[i][j] ;
        }
        delete  Values[i] ;
    }
    delete [] Values ;
    ///---------------------------------------
}


int _tmain(int argc, _TCHAR* argv[])
{
    std::vector<CProp> vProp;
    for(int i=0;i<3;++i)
    {
        CProp Prop;
        Prop.Set(10,20,5);
        vProp.push_back(Prop);
    }

    char ch;
    std::cin >> ch;

    return 0;
}



Автор: bsa 8.9.2010, 21:32
htzg, вот ты используешь в своей программе вектор. Почему бы его не использовать везде вместо new/delete?

Автор: htzg 8.9.2010, 23:39
это, кстати, хороший вопрос!
Элементы данного трех мерного массива в процессе работы программы будут очень часто меняться. Т.е. будут обращения к определенным элементам и присвоение им новых значений. Здесь критична скорость. 
Вопрос: обращение к элементам вектора через функцию at() или iterator будет происходить с такой же скоростью как через указатели в статическом массиве?
По мне так в случае с вектором должно быть медленнее.
Ваше мнение?

Автор: mes 9.9.2010, 00:07
Цитата(htzg @  8.9.2010,  22:39 Найти цитируемый пост)
 через функцию at() 

через at() будет медленее, так как имеется  проверка на попадание в диапазон
а через оператор[] при включенной оптимизации будет также.

Автор: borisbn 9.9.2010, 06:52
> Вопрос: обращение к элементам вектора через функцию at() или iterator будет происходить с такой же скоростью как
через указатели в статическом массиве?
1. Это зависит от реализации STL
2. Думаю эти расходы - ничто по сравнению с расходами самой программы, да и преждевременная оптимизация - корень зла (С) не помню чей ( м.б. Александреску? )
3. Всегда можно взять сначала адрес первого элемента вектора int * p = & array[ 0 ]; а затем использовать p[ i ]

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)