Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.54/13: Рейтинг темы: голосов - 13, средняя оценка - 4.54
0 / 0 / 2
Регистрация: 18.10.2015
Сообщений: 46

Сбрасываются значения переменных в структуре

09.10.2016, 19:36. Показов 2767. Ответов 7
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток.
Есть одна структура.
C++
1
2
3
4
5
6
struct
{
    bool   AllowInFile;
    bool   AllowInCLI;
    char * FileName;
} Vars;
Есть ещё один юнит-тест, который в самом начале задает в эту структуру значение переменных:
C++
1
2
3
Vars.AllowInCLI  = true;
Vars.AllowInFile = true;
Vars.FileName = "test.log";
Проблема в том, что когда начинается один из элементов теста (например, напечатать что-то в файл), то переменные сбрасываются. В чём может быть проблема? Или стоит обращаться к переменным другим способом?
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
09.10.2016, 19:36
Ответы с готовыми решениями:

Сбрасываются значения переменных при наследовании
Добрый день. Столкнулся с интересной проблемой от которой зависит все. Есть 3 класса: Класс 1: Public Class Variable_Mod ...

Значения переменных сбрасываются при нажатии на кнопку
Доброго времени суток! Пишу симулятор игры BlackJack и столкнулся с проблемой: В процедуре одной из кнопок имеется следующее: ...

При обращении к методу значения переменных сбрасываются на 0
Почему при обращении к методу CalculateTotalPerDiem() значения всех переменных сбрасывается на нуль? class ModelData { ...

7
Эксперт С++
 Аватар для schdub
3073 / 1411 / 425
Регистрация: 19.01.2009
Сообщений: 3,894
09.10.2016, 23:07
Chainik228, нужно глядеть код, как вы используете данную структуру. Если проблемы только с FileName, то скорее всего вместо
Цитата Сообщение от Chainik228 Посмотреть сообщение
C++
1
char * FileName;
нужно объявить как
C++
1
std::string FileName;
(не забудьте добавить #include <string>).
0
0 / 0 / 2
Регистрация: 18.10.2015
Сообщений: 46
10.10.2016, 03:34  [ТС]
Проблемы именно со всеми переменными, а не только с FileName.
Структура объявлена в заголовке именно в этом виде:
C++
1
2
3
4
5
6
struct
{
    bool   AllowInFile;
    bool   AllowInCLI;
    char * FileName;
} Vars;
Когда происходит обращение к функциям в том же заголовкам - значения сбрасываются. При этом в коде самих функций нет ничего, чтобы изменяло значения этих функций.
0
3178 / 1937 / 312
Регистрация: 27.08.2010
Сообщений: 5,131
Записей в блоге: 1
10.10.2016, 08:15
char* FileName - где буфер под строку? Наверняка, присваивается временный адрес и затирается стек.
0
0 / 0 / 2
Регистрация: 18.10.2015
Сообщений: 46
10.10.2016, 11:06  [ТС]
Сменил char * на string. Ничего не изменилось: при выполнение функций, переменные в структуре сбрасываются.
Проверял с отладчиком.
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
10.10.2016, 11:08
Цитата Сообщение от Chainik228 Посмотреть сообщение
Ничего не изменилось
Все-таки надо больше кода показать. Как используется, как создается и т.п. Само по себе описание этой структуры никак не поможет, ошибка где-то в другом коде, и нам ее не видно.
0
0 / 0 / 2
Регистрация: 18.10.2015
Сообщений: 46
10.10.2016, 11:52  [ТС]
Код теста:
Кликните здесь для просмотра всего текста
C++
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
#include <iostream>
 
#include "../src/log.h"
 
void fflog_ut1_Print ()
{
    ffLog::Print("Test Message", "Title", ffLog::TAG_NONE);
    ffLog::Print("Test Message", "Title", ffLog::TAG_DEBUG);
    ffLog::Print("Test Message", "Title", ffLog::TAG_FIXME);
    ffLog::Print("Test Message", "Title", ffLog::TAG_INFO);
    ffLog::Print("Test Message", "Title", ffLog::TAG_SUCCESS);
    ffLog::Print("Test Message", "Title", ffLog::TAG_WARNING);
    ffLog::Print("Test Message", "Title", ffLog::TAG_ERROR);
    ffLog::Print("Test Message", "Title", ffLog::TAG_FATALERROR);
}
 
void fflog_ut1_ClearFile ()
{
    ffLog::ClearFile();
}
 
int main(int argc, char ** argv)
{
    std::cout << "%SUITE_STARTING% fflog_ut1" << std::endl;
    std::cout << "%SUITE_STARTED%" << std::endl;
 
    ffLog::Vars.AllowInCLI  = true;
    ffLog::Vars.AllowInFile = true;
    ffLog::Vars.FileName = "test.log";
    
    std::cout << "%TEST_STARTED% fflog_ut1_Print (fflog_ut1)" << std::endl;
    fflog_ut1_Print();
    std::cout << "%TEST_FINISHED% fflog_ut1_Print (fflog_ut1)" << std::endl;
    
    std::cout << "%TEST_STARTED% fflog_ut1_ClearFile (fflog_ut1)" << std::endl;
    //fflog_ut1_ClearFile();
    std::cout << "%TEST_FINISHED% fflog_ut1_ClearFile (fflog_ut1)" << std::endl;
 
    std::cout << "%SUITE_FINISHED%" << std::endl;
 
    return (EXIT_SUCCESS);
}


Заголовок log.h
Кликните здесь для просмотра всего текста
C++
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
/**
 * @file log.h
 * @brief Функции журналирования.
 * Это заголовочный файл с функциями журналирования событий движка.
 */
#ifndef LOG_H
#define LOG_H
 
#include <string>
 
/**
 * @defgroup ffLog Функции журналирования.
 * В данном пространстве имен находятся функции журналирования событий.
 */
namespace ffLog
{
    // ---------------------------------------------------------------------- //
    /**
     * @brief Переменные.
     * Структура для хранения переменных данного модуля.
     * 
     * @ingroup ffLog
     */
    struct
    {
        /**
         * @brief Разрешить запись событий в файл.
         * Разрешить системе журналирования запись событий в файл.
         * 
         * @ingroup ffLog
         */
        bool        AllowInFile;
        /**
         * @brief Разрешить вывод событий в окно командной строки.
         * Разрешить системе журналирования вывод событий в окно командной
         * строки.
         * 
         * @ingroup ffLog
         */
        bool        AllowInCLI;
        /**
         * @brief Имя лог-файла.
         * Имя лог-файла, в который будет производиться запись. 
         * 
         * @ingroup ffLog
         */
        std::string FileName;
    } Vars;
    // ---------------------------------------------------------------------- //
    /**
     * @brief Максимальная длина сообщения.
     * 
     * @ingroup ffLog
     */
    extern const int MESSAGE_MAXLENGHT;
    /**
     * @brief Максимальная длина заголовка.
     * 
     * @ingroup ffLog
     */
    extern const int TITLE_MAXLENGHT;
    // ----
    enum : int
    {
        /**
         * @brief Пустая метка.
         * Нет цвета. Совсем.
         * 
         * @ingroup ffLog
         */
        TAG_NONE            = 0x00001000,
        /**
         * @brief Метка "debug" (отладка).
         * Сообщение не печатается, если отладочный режим движка не активен.
         * Цвет текста: бирюзовый.
         * 
         * @ingroup ffLog
         */
        TAG_DEBUG           = 0x00001001,
        /**
         * @brief Метка "fixme" (исправить).
         * Сообщение не печатается, если отладочный режим движка не активен.
         * Цвет текста: фиолетовый.
         * 
         * @ingroup ffLog
         */
        TAG_FIXME           = 0x00001002,
        /**
         * @brief Метка "info" (информация).
         * Нет цвета. Совсем.
         * 
         * @ingroup ffLog
         */
        TAG_INFO            = 0x00001003,
        /**
         * @brief Метка "success" (успех).
         * Сообщения об успехе чего-либо.
         * Цвет текста: зеленый.
         * 
         * @ingroup ffLog
         */
        TAG_SUCCESS         = 0x00001004,
        /**
         * @brief Метка "warning" (предупреждение).
         * Цвет текста: желтый.
         * 
         * @ingroup ffLog
         */
        TAG_WARNING         = 0x00001005,
        /**
         * @brief Метка "error" (ошибка).
         * Сообщение об ошибках, которые не являются критичными.
         * Цвет текста: красный.
         * 
         * @ingroup ffLog
         */
        TAG_ERROR           = 0x00001006,
        /**
         * @brief Метка "FATAL ERROR" (критическая ошибка).
         * Сообщение с этой меткой вызывают аварийное завершение движка.
         * Цвет фона: красный.
         * Цвет текста: белый.
         * 
         * @ingroup ffLog
         */
        TAG_FATALERROR      = 0x00001007
    };
    // ---------------------------------------------------------------------- //
    /**
     * @brief Печать сообщения.
     * Печать сообщения во внутриигровую консоль/терминал/лог-файл. Сообщение
     * форматируется с использованием управляющей последовательности как в 
     * printf(...). Заголовок НЕ форматируется, так что старайтесь не впихивать
     * управляющую последовательность туда.
     * 
     * @param[in] msg Сообщение (max. 4096 символов).
     * @param[in] title Заголовок для сообщения (max. 32 символа).
     * @param[in] tag Метка для сообщения (константы вида ffLog::TAG_*).
     * @param[in] ... Значения для подстановки.
     * 
     * @ingroup ffLog
     */
    void Print ( char * msg, char * title, int tag, ... );
    // ---------------------------------------------------------------------- //
    /**
     * @brief Очистить лог-файл.
     * Открывает лог-файл и очищает его.
     * 
     * @ingroup ffLog
     */
    void ClearFile ();
    // ---------------------------------------------------------------------- //
}
 
#endif /* LOG_H */


Код log.cpp
Кликните здесь для просмотра всего текста
C++
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
#include "log.h"
 
#include <cstdarg>
#include <cstdio>
#include <fstream>
#include <iostream>
#include <string>
#include <sstream>
 
using namespace std;
 
namespace ffLog
{
    // ---------------------------------------------------------------------- //
    const int MESSAGE_MAXLENGHT         = 4096;
    const int TITLE_MAXLENGHT           = 32;
    // ---------------------------------------------------------------------- //
    /**
     * @brief Конвертировать номер метки в строку.
     * 
     * @param tag Метка в виде номера.
     * @return Метка в виде строка.
     */
    inline string GetTagAsString ( int tag )
    {
        switch (tag)
        {
            default:
            case TAG_NONE:
                return string("");
            case TAG_DEBUG:
                return string("[debug]>");
            case TAG_FIXME:
                return string("[ fix ]>");
            case TAG_INFO:
                return string("[info ]>");
            case TAG_SUCCESS:
                return string("[ :-) ]>");
            case TAG_WARNING:
                return string("[  !  ]>");
            case TAG_ERROR:
                return string("[ !!! ]>");
            case TAG_FATALERROR:
                return string("[FATAL]>");
        }
    }
    /**
     * @brief Конвертировать номер метки в символ цвета.
     * Используются ANSI Escape-последовательности.
     * 
     * @param tag Метка в виде номера.
     * @return Символ цвета для метки.
     */
    inline string GetTagColor ( int tag )
    {
        switch (tag)
        {
            default:
            case TAG_NONE:
            case TAG_INFO:
                return string("");
            case TAG_DEBUG:
                return string("\x1b[36m");
            case TAG_FIXME:
                return string("\x1b[35m");
            case TAG_SUCCESS:
                return string("\x1b[32m");
            case TAG_WARNING:
                return string("\x1b[33m");
            case TAG_ERROR:
                return string("\x1b[31m");
            case TAG_FATALERROR:
                return string("\x1b[37,41m");
        }
    }
    /**
     * @brief Печать сообщения в консоль.
     * Не использовать напрямую!
     * 
     * @param msg Сообщение.
     * @param title Заголовок.
     * @param tag Метка.
     */
    inline void PrintInConsole ( char msg [MESSAGE_MAXLENGHT],
                                 char title [TITLE_MAXLENGHT],
                                 int tag )
    {
        // @todo: Вывод в консоль (а сначала сделай консоль!).
    }
    /**
     * @brief Печать сообщения в терминал.
     * Не использовать напрямую!
     * 
     * @param msg Сообщение.
     * @param title Заголовок.
     * @param tag Метка.
     */
    inline void PrintInTerminal ( char msg [MESSAGE_MAXLENGHT],
                                  char title [TITLE_MAXLENGHT],
                                  int tag )
    {
        if (!Vars.AllowInCLI) return;
        
        cout << GetTagColor(tag) << GetTagAsString(tag) << "\x1b[0m ";
        
        if (title != NULL)
            cout << title << ": ";
        
        cout << msg << endl;
    }
    /**
     * @brief Печать сообщения в файл.
     * Не использовать напрямую!
     * 
     * @param msg Сообщение.
     * @param title Заголовок.
     * @param tag Метка.
     */
    inline void PrintInFile ( char msg [MESSAGE_MAXLENGHT],
                              char title [TITLE_MAXLENGHT],
                              int tag )
    {
        if (!Vars.AllowInFile) return;
        
        ofstream outstr (Vars.FileName, ios::in | ios::ate);
        
        outstr << GetTagAsString(tag);
        
        if (title != NULL)
            outstr << title << ": ";
        
        outstr << msg << endl;
        
        outstr.close();
    }
    // ---------------------------------------------------------------------- //
    void Print ( char msg [MESSAGE_MAXLENGHT], char title [TITLE_MAXLENGHT],
                 int tag, ... )
    {
        va_list ap;
        char msgbuf [MESSAGE_MAXLENGHT];
        
        va_start(ap, tag);
        vsnprintf(msgbuf, MESSAGE_MAXLENGHT, msg, ap);
        va_end(ap);
        
        PrintInConsole(msgbuf, title, tag);
        PrintInTerminal(msgbuf, title, tag);
        PrintInFile(msgbuf, title, tag);
        
        //if (tag == TAG_FATALERROR)
        //    exit();
    }
    // ---------------------------------------------------------------------- //
    void ClearFile ()
    {
        ofstream outstr (Vars.FileName, ios::in | ios::trunc);
        outstr.close();
    }
    // ---------------------------------------------------------------------- //
}
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
10.10.2016, 12:39
Лучший ответ Сообщение было отмечено Chainik228 как решение

Решение

Chainik228, надо структуре дать имя, а переменную Vars создать в Log.cpp, а в заголовочном файле оставить объявление
C++
1
extern VarsStructName Vars;
Сейчас похоже, что на каждую единицу трансляции образовалось по своей копии Vars с внутренним связыванием. Поэтому и создается эффект "сбрасывания" значений.

Добавлено через 1 минуту
PS. вообще лучше взять за правило не создавать глобальных переменных в заголовочном файле.

Добавлено через 18 минут
Довольно необычный пример ошибки, связанной с глобальными переменными с внутренним связыванием. Обычно на такое напарываются в случае со static переменными в заголовочном файле или переменными в анонимном пространстве имен. Но тут дело интереснее, переменная имеет внутренее связывание, потому что тип анонимной структуры связывания не имеет вообще (no-linkage, в силу своей анонимности). При этом, насколько я понимаю, требования делать такую переменную с внутренним связыванием в стандарте нет. Есть вот такое:
A name with no linkage (notably, the name of a class or enumeration declared in a local scope (3.3.2)) shall not be used to declare an entity with linkage.
Т.е. согласно этому, тут должна быть ошибка компиляции. Но компилятор почему-то делает этой переменной внутренее связывание.
2
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
10.10.2016, 12:39
Помогаю со студенческими работами здесь

Сбрасываются значения компонента option
Добрый вечер, форумчане! Возникла небольшая неприятность при создании простого калькулятора. Имеются три поля для ввода значений, и два...

Даны значения двух переменных a и b. Поменять местами значения этих переменных
1) Обмен значениями. Даны значения двух переменных a и b. Поменять местами значения этих переменных.

При переходах по формам значения Combobox-ов сбрасываются
Создал 5 форм, на одной форме есть serial port, в другой форме настройка для порта, на следующей форме отправляю команды на порт... Вся...

Проверка переменных в структуре
Вопрос как проверить переменные в структуре: struct blocknode { unsigned int bsize; bool free; unsigned char *bptr; ...

Непонятная перезапись переменных в структуре
Доброго времени суток, господа форумчане! На досуге столкнулся с одной любопытной проблемой, касающейся поведения char`овских переменных...


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

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
Программная установка даты и запрет ее изменения
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: при создании документов установить период списания автоматически. . .
Вывод данных в справочнике через динамический список
Maks 01.04.2026
Реализация из решения ниже выполнена на примере нетипового справочника "Спецтехника" разработанного в конфигурации КА2. Задача: вывести данные из ТЧ нетипового документа. . .
Функция заполнения текстового поля в реквизите формы документа
Maks 01.04.2026
Алгоритм из решения ниже реализован на нетиповом документе "ВыдачаОборудованияНаСпецтехнику" разработанного в конфигурации КА2, в дополнении к предыдущему решению. На форме документа создается. . .
К слову об оптимизации
kumehtar 01.04.2026
Вспоминаю начало 2000-х, университет, когда я писал на Delphi. Тогда среди программистов на форумах активно обсуждали аккуратную работу с памятью: нужно было следить за переменными, вовремя. . .
Идея фильтра интернета (сервер = слой+фильтр).
Hrethgir 31.03.2026
Суть идеи заключается в том, чтобы запустить свой сервер, о чём я если честно мечтал давно и давно приобрёл книгу как это сделать. Но не было причин его запускать. Очумелые учёные напечатали на. . .
Модель здравосоХранения 6. ESG-повестка и устойчивое развитие; углублённый анализ кадрового бренда
anaschu 31.03.2026
В прикрепленном документе раздумья о том, как можно поменять модель в будущем
10 пpимет, которые всегда сбываются
Maks 31.03.2026
1. Чтобы, наконец, пришла маршрутка, надо закурить. Если сигарета последняя, маршрутка придет еще до второй затяжки даже вопреки расписанию. 2. Нaдоели зима и снег? Не надо переезжать. Достаточно. . .
Перемещение выделенных строк ТЧ из одного документа в другой
Maks 31.03.2026
Реализация из решения ниже выполнена на примере нетипового документа "ВыдачаОборудованияНаСпецтехнику" с единственной табличной частью "ОборудованиеИКомплектующие" разработанного в конфигурации КА2. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru