77 / 50 / 16
Регистрация: 17.05.2015
Сообщений: 262
1

Странное поведение std::deque в Qt

11.02.2016, 05:12. Показов 525. Ответов 2
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Добрый день!
Очень странно себя ведет std::deque в котором хранятся указатели.
simpleOrganism.h
Кликните здесь для просмотра всего текста
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#ifndef SIMPLEORGANISM_H
#define SIMPLEORGANISM_H
 
#include <QObject>
#include <QList>
#include <QListIterator>
#include <QMutableListIterator>
#include <QDebug>
#include <QtMath>
 
 
#include <cmath>
#include <time.h>
#include "dna.h"
#include <vector>
#include <deque>
 
//#include <thread>
//#include <mutex>
 
struct statistic {
    int mutations;
    int alives;
    int deads;
    int creates;
    int delete_objects;
    int size_pull;
    int del_test;
 
};
 
class SimpleOrganism : public QObject
{
    //std::mutex g_mutex;
    Q_OBJECT
public:
    const double LIFE_INTERVAL = 0.1;
    static int GLOBAL_ID_ORGANISM;
    static int GLOBAL_CLASS_ORGANISM;;
   static std::deque<SimpleOrganism *> pull_organism;
 
    explicit SimpleOrganism(QObject *parent = 0);
    explicit SimpleOrganism(SimpleOrganism *parent_organism, QObject *parent = 0);
    ~SimpleOrganism();
    DNA * dna;
 
    bool life;
 
    int get_id();
    int get_class();
    bool lifecicle();
    static bool global_life_cicle();
    void clone();
    void death();
    bool get_life();
    void show();
    static void show_stat();
private:
    int ID_Organism;
    int Class_organism;
 
    struct parametrs {
        double outer_shell; //внешняя оболочка толщина   [1]
        double inner_shell; //внутреняя оболочка толщина [2]
        double insides;     //внутренности толщина       [3]
        double force;       //массивность/сила/etc. [4]
        double density;     //плотность             [5]
        double life_cicle;      //жизненный цыкл.      [8]
    } max_param, current_param;
 
   static statistic stat;
 
    struct movement {
        double speed;
        float direction; //направление 360градусов
        float acceleration = 0; //разгон, макс 100% 1.0.
        bool move;
        double posX, posY;
    } move;
 
    double size;        //общая толщина. (радиус)
    double hungry;      //голод
    //bool life;
 
    bool dna_calc();
    bool param_calc();
    bool push_pull();
 
signals:
 
public slots:
};
 
#endif // SIMPLEORGANISM_H


SimpleOrganism.cpp
Кликните здесь для просмотра всего текста
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
#include "simpleorganism.h"
 
int SimpleOrganism::GLOBAL_ID_ORGANISM = 0;
int SimpleOrganism::GLOBAL_CLASS_ORGANISM = 0;
statistic SimpleOrganism::stat;
 
std::deque<SimpleOrganism *> SimpleOrganism::pull_organism;
 
SimpleOrganism::SimpleOrganism(QObject *parent) : QObject(parent)
{
    ID_Organism = GLOBAL_ID_ORGANISM;
    GLOBAL_ID_ORGANISM++;
 
    Class_organism = GLOBAL_CLASS_ORGANISM;
    GLOBAL_CLASS_ORGANISM++;
 
 
    dna = new DNA(this);
    dna_calc();
 
}
 
SimpleOrganism::SimpleOrganism(SimpleOrganism *parent_organism, QObject *parent) : QObject(parent)
{
    ID_Organism = GLOBAL_ID_ORGANISM;
    GLOBAL_ID_ORGANISM++;
 
    Class_organism = parent_organism->get_class();
 
    dna = new DNA(parent_organism->dna, this);
    dna_calc();
}
 
SimpleOrganism::~SimpleOrganism() {
    stat.delete_objects++;
}
 
bool SimpleOrganism::dna_calc() {
    stat.alives++;
    stat.creates++;
 
    max_param.insides = log(dna->get_dna_block(3)) / log(1.01); //внутренности от ДНК
    max_param.outer_shell = max_param.insides / 20 + (log(dna->get_dna_block(1)) / log(1.1) / 2); //внешняя оболочка, зависит от размеров внутренностей и ДНК
    max_param.inner_shell = max_param.insides / 20 + (log(dna->get_dna_block(2)) / log(1.1) / 2); //внутренняя оболочка, зависит от размера внутренностей и ДНК
    max_param.force = log(dna->get_dna_block(4)) / log(1.01); //мощность.
    max_param.density = log(dna->get_dna_block(5)) / log(1.1); // чем выше плотность - тем прочнее и медленнее создание.
    max_param.life_cicle = log(dna->get_dna_block(8)) / log(1.1);
 
    current_param.life_cicle = LIFE_INTERVAL;
 
    life = true;
    hungry = 1;
    return true;
}
 
bool SimpleOrganism::param_calc() {
 
    double procent_life = current_param.life_cicle / max_param.life_cicle;
    current_param.insides = max_param.insides * procent_life;
    current_param.outer_shell = max_param.outer_shell * procent_life;
    current_param.inner_shell = max_param.inner_shell * procent_life;
    current_param.force = max_param.force * procent_life;
    current_param.density = max_param.density * procent_life;
 
    size = current_param.insides + current_param.inner_shell + current_param.outer_shell;
    double temp_speed = current_param.force - ((size * (current_param.density / 10)) / 20);
    if (move.move) {
        if (move.acceleration < 1)
            move.acceleration += 0.1;
    }
    else {
        if (move.acceleration > 0)
            move.acceleration -= 0.1;
    }
    move.speed = temp_speed * move.acceleration;
 
    return true;
}
 
bool SimpleOrganism::lifecicle() {
    if (!life)
        return false;
 
    //смерть от голода.
    if (hungry >= 100) {
        death();
        return false;
    }
 
    //Вероятность смерти от старости
    if (current_param.life_cicle > max_param.life_cicle) {
        if (rand() % 100+1 <= current_param.life_cicle / max_param.life_cicle * 100 - 100) {
            death();
            return false;
        }
    }
 
    current_param.life_cicle += LIFE_INTERVAL;
 
    //Голод
    //if (hungry < 100)
   //     hungry++;
 
    if (rand() % 1000 <= 1) {
        dna->mutations();
        stat.mutations++;
    }
 
    if (current_param.life_cicle / max_param.life_cicle * 100 + (rand() % 40) - hungry >= 100 ) {
        clone();
        return false;
    }
 
    param_calc();
    return true;
}
 
bool SimpleOrganism::global_life_cicle() {
    int z = pull_organism.size();
    for (int i = 0; i < z; ++i) {
        pull_organism[i]->lifecicle();
    }
 
    if (!pull_organism.back()->get_life()) {
        stat.del_test++;
    }
 
   // pull_organism.back()->show();
    if (stat.delete_objects > 100000) {
        stat.delete_objects = 0;
        pull_organism.shrink_to_fit();
    }
 
    return true;
}
 
 
void SimpleOrganism::death() {
    life = false;
    stat.deads++;
    stat.alives--;
}
 
void SimpleOrganism::clone() {
    //pull_organusm.push_back(new SimpleOrganism(this, 0));
    //pull_organusm.push_back(new SimpleOrganism(this, 0));
    pull_organism.push_front(new SimpleOrganism(this, 0));
    pull_organism.push_front(new SimpleOrganism(this, 0));
    death();
}
 
int SimpleOrganism::get_class() {
    return Class_organism;
}
 
int SimpleOrganism::get_id() {
    return ID_Organism;
}
 
bool SimpleOrganism::get_life() {
    return life;
}
 
bool SimpleOrganism::push_pull() {
    pull_organism.push_front(this);
    return true;
}
 
 
void SimpleOrganism::show_stat() {
    qDebug() << "\n####STATS:####"
             << "\n creates - " << stat.creates
             << "\n lifes - " << stat.alives
             << "\n deads - " << stat.deads
             << "\n mutations - " << stat.mutations
             << "\n delete obj - " << stat.delete_objects
             << "\n size_pull - " << stat.size_pull
             << "\n del test - " << stat.del_test
             << "\n#############\n";
}
 
void SimpleOrganism::show() {
    qDebug() << "life " << life
             << "\n life cicle " << current_param.life_cicle;
 
}


main.cpp
Кликните здесь для просмотра всего текста
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <QCoreApplication>
#include <QProcess>
#include "simpleorganism.h"
#include <iostream>
#include <time.h>
#include <QDebug>
int main(int argc, char *argv[])
{
    clock_t t;
    QCoreApplication a(argc, argv);
    srand(time(NULL));
    SimpleOrganism::pull_organism.clear();
    for (int i = 0; i < 100; ++i)
        SimpleOrganism::pull_organism.push_front(new SimpleOrganism());
 
    for (int i = 0; i < 10000; ++i) {
        t = clock();
        SimpleOrganism::global_life_cicle();
        SimpleOrganism::show_stat();
        t = clock() - t;
        qDebug() << "\ntime " << t;
 
    }
 
 
    return a.exec();
}


Внимание на функцию bool SimpleOrganism::global_life_cicle();
В ней перебирается весь контейнер (пробовал по итератору, через функцию .at(index) и просто по индексу [index]. Тут все нормально вызывается, хотя Qtcreator не видит функции объектов, не подсвечивает у них синтаксис и прочее.

В функции clone обьект создает новые свои копии и помещает в начало очереди.

Ниже идет условие:
C++ (Qt)
1
2
3
if (!pull_organism.back()->get_life()) {
        stat.del_test++;
    }
get_life() возвращает переменную life, которая булево. Так вот по не ведомой мне причине, очередь всегда возвращает true. Даже когда life давно уже false.
Для теста я сделал так (вынес переменную life в public)
C++ (Qt)
1
2
3
if (!pull_organism.back()->life) {
        stat.del_test++;
    }
И угадайте что? - правильно, оно опять возвращает true.

Меня это взбесило, я сделал так. Я создал функцию такого содержания.
C++ (Qt)
1
2
3
4
5
6
7
//костыль
void SimpleOrganism::delete_back() {
if (!life) {
    pull_organism.pop_back();
    stat.del_test++;
}
}
а в global_life_cicle сделал просто функцию, которая впыолняет так: pull_organism.back()->delete_back();
и знаете что? опять оно возвращает мне вегда true!

И тут я сделал сдледующее.. В main я убрал цыкл, что бы создался ОДИН обьект.
C++ (Qt)
1
2
//for (int i = 0; i < 100; ++i) //Закоментил
        SimpleOrganism::pull_organism.push_front(new SimpleOrganism());
и стало нормально все работать.
Что с очередью не так? Почему QtCreator не видит что внутри? Почему она себя так странно ведет?

п.с. за место stat.del_test должно быть delete this, это если кто-то решит что память течет.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
11.02.2016, 05:12
Ответы с готовыми решениями:

Странное поведение std::string, полученного из std::stringstream
Есть код #include &lt;iostream&gt; #include &lt;sstream&gt; #include &lt;cstring&gt; int main() { ...

Странное поведение std::vector
Есть std::vector, в котором валяются элемент типа std:: pair. Есть цикл типа: while (true) { ...

Странное рекурсивное поведение объекта std::cout
Пытался организовать очередь при помощи шаблона и наткнулся на &quot;странное&quot; поведение: //...

Странное поведение операции XOR и std::cin
Объясните, пожалуйста, почему этот код работает правильно: /* Обмен значений двух переменных без...

2
Эксперт по математике/физикеЭксперт С++
2044 / 1363 / 393
Регистрация: 16.05.2013
Сообщений: 3,500
Записей в блоге: 6
11.02.2016, 07:57 2
В конструкторе life присаваивается true. Только в функции void SimpleOrganism::death() устанавливается для нее значение false. Отсюда вопрос где вызов этой функции?
0
77 / 50 / 16
Регистрация: 17.05.2015
Сообщений: 262
11.02.2016, 08:42  [ТС] 3
Цитата Сообщение от Ilot Посмотреть сообщение
Отсюда вопрос где вызов этой функции?
death вызывается в двух местах.
где цикл жизни просчитывается в life_cicle();. Строка if (current_param.life_cicle > max_param.life_cicle)
Либо в clone(), когда обьект создает свои копии и убивает себя в строке if (current_param.life_cicle / max_param.life_cicle * 100 + (rand() % 40) - hungry >= 100 ).
0
11.02.2016, 08:42
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
11.02.2016, 08:42
Помогаю со студенческими работами здесь

std::deque
Как известно при добавлении в конец вектора элементов(и не только в конец) может возникнуть...

Как работает std::deque?
Пытаюсь разобраться в работе std-шного дека. Веб-серфинг дал следующее: Данные хранятся в куче...

Как устроена std::deque внутри ?
Не могу себе представить возможную внутреннюю реализацию этого контенера, чтоб она удовлетворяла...

Разделить std::deque на заданное количество деков
Имеется дек, нужно его разделить на отдельные деки. Это задание я сделал когда знал точное...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru