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

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

09.10.2016, 19:36. Показов 2714. Ответов 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
3176 / 1935 / 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
19497 / 10102 / 2461
Регистрация: 30.01.2014
Сообщений: 17,813
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
19497 / 10102 / 2461
Регистрация: 30.01.2014
Сообщений: 17,813
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
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru