Не выделяется память в std::vector
От: RussianFellow Россия http://russianfellow.livejournal.com
Дата: 29.12.18 08:22
Оценка:
В моём проекте, разрабатываемом на Visual Studio 2012, я помещаю структуру моего типа MyStruct в std::vector<MyStruct> . Размер структуры MyStruct -- 16008 байт.
При помещении в этот вектор с помощью функции push_back у меня в отладчике выскакивает следующее сообщение об ошибке:

Необработанное исключение по адресу 0x00F12979 в MyProject.exe:
0xC000041D: Во время обратного вызова пользователя обнаружено необработанное исключение.


При этом отладчик останавливается в файле vector в функции:

bool _Inside(const value_type *_Ptr) const
{
    return (_Ptr < this->_Mylast && this->_Myfirst <= _Ptr);
}


При попытке выделить память в этом векторе с помощью функции reserve(sizeof(MyStruct)); у меня в отладчике выскакивает следующее сообщение об ошибке:

Необработанное исключение по адресу 0x00A633C9 в MyProject.exe:
0xC000041D: Во время обратного вызова пользователя обнаружено необработанное исключение.


При этом отладчик останавливается в файле vector в функции:

size_type capacity() const _NOEXCEPT
{
    return (this->_Myend - this->_Myfirst);
}


Что это означает? Как решить эту проблему--как поместить структуру типа MyStructm размером в 16008 байт в std::vector<MyStruct> ?
1613 г. = 2024 г.
Re: Не выделяется память в std::vector
От: Amygdala Россия  
Дата: 29.12.18 08:28
Оценка:
Здравствуйте, RussianFellow, Вы писали:

Покажи код и структуру. Многопоточность используешь?
Проблема 100% не в std::vector.
Re: Не выделяется память в std::vector
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 29.12.18 08:29
Оценка:
Здравствуйте, RussianFellow, Вы писали:

RF>Что это означает? Как решить эту проблему--как поместить структуру типа MyStructm размером в 16008 байт в std::vector<MyStruct> ?


Для начала начни обрабатывать исключения:

Exceptions

* std::length_error if new_cap > max_size().
* any exception thrown by Allocator::allocate() (typically std::bad_alloc)

If an exception is thrown, this function has no effect (strong exception guarantee).
If T's move constructor is not noexcept and T is not CopyInsertable into *this, vector will use the throwing move constructor. If it throws, the guarantee is waived and the effects are unspecified.

Re: Не выделяется память в std::vector
От: reversecode google
Дата: 29.12.18 08:30
Оценка: +2
запишитесь на какие то курсы по С++
консультациями на форуме их не изучить, если даже с такой ерундой сами разобраться не можете
Re: Не выделяется память в std::vector
От: Stanislav V. Zudin Россия  
Дата: 29.12.18 08:48
Оценка: +1
Здравствуйте, RussianFellow, Вы писали:

Согласен с коллегами, ошибка в векторе наведенная, накосячил где-то ранее.

RF>При попытке выделить память в этом векторе с помощью функции reserve(sizeof(MyStruct)); у меня в отладчике выскакивает следующее сообщение об ошибке:


Обращаю твое внимание, что здесь ты пытаешься выделить память под массив из 16008 элементов (reserve принимает размер в штуках, а не в байтах).

Ну и напоследок, а точно нужна структура такого размера?
_____________________
С уважением,
Stanislav V. Zudin
Re: Не выделяется память в std::vector
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 31.12.18 09:34
Оценка:
Здравствуйте, RussianFellow, Вы писали:

RF>В моём проекте, разрабатываемом на Visual Studio 2012, я помещаю структуру моего типа MyStruct в std::vector<MyStruct> . Размер структуры MyStruct -- 16008 байт.

RF>При помещении в этот вектор с помощью функции push_back у меня в отладчике выскакивает следующее сообщение об ошибке:

Это нужно MyStruct смотреть.

RF>При попытке выделить память в этом векторе с помощью функции reserve(sizeof(MyStruct)); у меня в отладчике выскакивает следующее сообщение об ошибке:


Это сильно. 16008 — это какое то волшебное число, что ты его везде пихаешь?

reserve(sizeof(MyStruct)) это выделение памяти для 16008 элементов, каждый из которых занимает 16008 байт. Итого — 256256064 байт.

Не ахти какой объем.

Но если у тебя там есть еще аналогичный код и сборка под 32-бита, то да — памяти может и не хватить.

RF>Что это означает? Как решить эту проблему--как поместить структуру типа MyStructm размером в 16008 байт в std::vector<MyStruct> ?


Ну не знаю, может надо таки начать с чтения "С++ для чайников", как я тебе советовал
Автор: Коваленко Дмитрий
Дата: 09.12.18
?

---
Я вот думаю, если это стеб, то достаточно неплохой

Может это какой препод таким образом глумится над кодом студентов?

Лаптев?
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re: Не выделяется память в std::vector
От: RussianFellow Россия http://russianfellow.livejournal.com
Дата: 09.01.19 08:39
Оценка:
Раз уж просят код с студию, то вот, пожалуйста:

class Perturbation
{
public:
    virtual  T3DVector Forc(long jt, LDouble tj,T3DVector* r)=0;
};

typedef vector < Perturbation* > Perts;

class Perturbation_set
{
protected:
  Perts arr;

public:
    T3DVector  Forc(long jt, LDouble tj,T3DVector* r)
    {
        T3DVector result(0,0,0);
        for (Perts::iterator i =arr.begin(); i != arr.end(); i++)
        {
            Perturbation* p = (*i);
            result+= p->Forc(jt,tj,r);
        }
        return result;
    };
    T3DVector TwoBod(long jt, LDouble tj,T3DVector* r)
    {
        T3DVector f;
//        f = (*(arr.begin()))->Forc(jt,tj,r);
        f = (*(arr.end()-1))->Forc(jt,tj,r);
        return f;
    }
    int addPerturbation(Perturbation* perturbation)
    {
        arr.push_back(perturbation);
        return arr.size();
    }
    int GetSize()
    {
        return arr.size();
    }
    int setPerturbation(Perturbation* perturbation, int i)
    {
        arr[i] = perturbation;
        return arr.size();
    }
    void reserve(long size)
    {
        arr.reserve(size);
    }
};

class GravField : virtual public Perturbation
{
public:  
    int No,Nk;
    LDouble r_grav[20];
// длина массивов c и s для поля n0xn0 должна равняться - {(n0-1)*2+n0*(n0-1)/2}
    LDouble c[700]; //36x36
    LDouble s[700]; //36x36
//    LDouble *c;

    GravField(char* NAMEpol,int n0, int ntes);
    virtual T3DVector Forc(long jt, LDouble tj,T3DVector* r);

/*  static int nt ;
    static LDouble sq[65];
    static LDouble sk[32];*/

protected:
    int nt ;
    LDouble sq[201];
    LDouble sk[100];
    LDouble hp[37];
    int nai[478];
};

class SunEarthAroundMoon : public Perturbation
{
public:
    LDouble m_Kappa;
    short n_planet;
    long  mysize;
    GravField* m_EarthGrav;
    Perturbation_set* m_EarthGravPerturb;
    SunEarthAroundMoon(ModelForc *ff)
    {
        int  i1, fg;

        m_Sun = ff->Sun;
        if (m_Sun == 1) SUN_MOON.List_Planet[10]=1;
        m_Earth = ff->Moon;
        if (m_Earth == 1) SUN_MOON.List_Planet[2]=1;
        m_SunPr = ff->SunPr;
        if (m_SunPr == 1) SUN_MOON.List_Planet[10]=1;
        m_Kappa = ff->m_Kappa;
//учет влияния планет begin
        n_planet=0;
        for(int i=0; i<9; i++)
        {
            if(ff->List_Planet[i] == 1)
            {
                SUN_MOON.List_Planet[i]=1;
                n_planet++;
            }
        }
        if (n_planet != 0) SUN_MOON.List_Planet[10]=1;
//учет влияния планет end
        if ((ff->m_MEF.n0>0)||(ff->m_MEF.ntes>0))
        // нецентральное гравитационное поле Земли
        {
            nz = ff->m_MEF.n0;
            nt = ff->m_MEF.ntes;
            i1 = (ff->m_MEF.flag)/10;
            fg = ff->m_MEF.flag - i1*10;
            if (fg==1)
            {
                m_EarthGrav = new GravField(ff->m_MEF.NAMEpol,nz,nt);
                //mysize = sizeof(GravField);
                //m_EarthGravPerturb->reserve(mysize); // здесь бьётся программа
                //m_EarthGravPerturb->reserve(1); // здесь бьётся программа
                m_EarthGravPerturb->addPerturbation(m_EarthGrav); // здесь бьётся программа
            }
        }
    }
    ~SunEarthAroundMoon(){};
    virtual  T3DVector Forc(long jt, LDouble tj,T3DVector* r);
protected:
    int m_Sun;
    int m_Earth;
    int m_SunPr;
    ParVectErthForc m;
    int nz;
    int nt;
};


Что я делаю не так?
1613 г. = 2024 г.
Re[2]: Не выделяется память в std::vector
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 09.01.19 10:10
Оценка: 4 (1)
RF>Что я делаю не так?

Если бы ты написал: Perturbation_set* m_EarthGravPerturb = nullptr;
То найти ошибку было бы проще. Почему члены класса не инициализируешь? Сколько лет опыта для таких глупых ошибок?
Re[3]: Не выделяется память в std::vector
От: RussianFellow Россия http://russianfellow.livejournal.com
Дата: 09.01.19 10:28
Оценка:
Здравствуйте, Nuzhny, Вы писали:

RF>>Что я делаю не так?


N>Если бы ты написал: Perturbation_set* m_EarthGravPerturb = nullptr;

N>То найти ошибку было бы проще. Почему члены класса не инициализируешь? Сколько лет опыта для таких глупых ошибок?

Часть кода из приведённого не я писал.
1613 г. = 2024 г.
Re[4]: Не выделяется память в std::vector
От: Amygdala Россия  
Дата: 09.01.19 10:34
Оценка:
Здравствуйте, RussianFellow, Вы писали:

RF>Часть кода из приведённого не я писал.


Код ужасен весь.

    int setPerturbation(Perturbation* perturbation, int i)
       {
            arr[i] = perturbation;
            return arr.size();
        }


Где сравнение на выход из диапазона?

LDouble r_grav[20];
    LDouble c[700]; //36x36
    LDouble s[700]; //36x36
    int nt ;
    LDouble sq[201];
    LDouble sk[100];
    LDouble hp[37];
    int nai[478];


Вау, меджик намберс. Нет слов.

    GravField* m_EarthGrav;
    Perturbation_set* m_EarthGravPerturb;

    if ((ff->m_MEF.n0>0)||(ff->m_MEF.ntes>0))
        // нецентральное гравитационное поле Земли
        {
            nz = ff->m_MEF.n0;
            nt = ff->m_MEF.ntes;
            i1 = (ff->m_MEF.flag)/10;
            fg = ff->m_MEF.flag - i1*10;
            if (fg==1)
            {
                m_EarthGrav = new GravField(ff->m_MEF.NAMEpol,nz,nt);
                //mysize = sizeof(GravField);
                //m_EarthGravPerturb->reserve(mysize); // здесь бьётся программа
                //m_EarthGravPerturb->reserve(1); // здесь бьётся программа
                m_EarthGravPerturb->addPerturbation(m_EarthGrav); // здесь бьётся программа
            }
        }


m_EarthGravPerturb не инициализируется в конструкторе, но в него начинаешь добавлять элементы? Кстати — это и есть причина начальной ошибки.


Код ужасен. Весь!
Отредактировано 09.01.2019 10:36 Amygdala . Предыдущая версия .
Re[4]: Не выделяется память в std::vector
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 09.01.19 10:39
Оценка:
Здравствуйте, RussianFellow, Вы писали:

RF>Часть кода из приведённого не я писал.


Хорошо. Но:
1. Переменные всё равно лучше инициализировать сразу. Ещё хорошей практикой является объявление переменных не в начале функций а в момент их использования, например: int i1, fg;
Такого лучше избегать, в том месте это вообще лишнее. И теперь можно инициализировать члены класса не только в конструкторе, но и сразу при объявлении. Не пренебрегай этим, многие ошибки сразу исчезнут сами собой. Это защита как от забывчивости, так и логически верно: конструкторов может быть много, не надо копи-пастить инициализацию.
1. Начни обрабатывать исключения. Я уже давал ссылку выше, сделай try-catch и посмотри, что происходит. Это норма для С++ следить за тем, что память выделяется или не выделяется.
2. Если первое не помогло, то сделай из своего большого проекта минимальный приводящий к ошибке. Комментируй, убирай функции и куски кода. Пользуйся отладчиков. Используй тулзы для отслеживания затираний/утечек памяти.
Re[5]: Не выделяется память в std::vector
От: Amygdala Россия  
Дата: 09.01.19 10:41
Оценка:
Здравствуйте, Nuzhny, Вы писали:

N>Хорошо. Но:

N> Используй тулзы для отслеживания затираний/утечек памяти.

Да проще все. Он не выделил память под m_EarthGravPerturb, но начинает его активно использовать.
Re[4]: Не выделяется память в std::vector
От: RussianFellow Россия http://russianfellow.livejournal.com
Дата: 09.01.19 13:01
Оценка:
Здравствуйте, RussianFellow, Вы писали:

А, всё, я разобрался.
Нужно было написать:

m_EarthGravPerturb = NULL;

а потом:

m_EarthGravPerturb = new Perturbation_set();

Теперь всё работает!
1613 г. = 2024 г.
Re[5]: Не выделяется память в std::vector
От: Amygdala Россия  
Дата: 09.01.19 13:07
Оценка:
Здравствуйте, RussianFellow, Вы писали:

RF>А, всё, я разобрался.


Две недели не мог разобраться, а через три часа после того как я указал на ошибку, вдруг резко разобрался?
Молодец чо.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.