Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.80/5: Рейтинг темы: голосов - 5, средняя оценка - 4.80
0 / 0 / 0
Регистрация: 07.09.2019
Сообщений: 5

Странное поведение при передаче структуры в поток

07.09.2019, 09:49. Показов 1089. Ответов 7

Студворк — интернет-сервис помощи студентам
Добрый день! Долгое время пишу только на С# и Qt. Мозги совсем атрофировались от низкоуровневого кода. Но пришлось решать задачу с малыми ресурсами и максимальной скоростью. Математику задачи решил и реализовал. Но потребовалось асинхронное выполнение некоторых функций - сетевой копирование файлов, объемом > 2 Тбайт. Решил выкинуть в поток. И тут возникла проблема.

Структура для потока:
C++
1
2
3
4
5
6
7
struct ARGS
{
    TCHAR pszFileSrc[MAX_PATH];
    TCHAR pszFileDst[MAX_PATH];
    HWND m_test;
    HWND m_Main;
};
Кусок кода потока:

C++
1
2
3
4
5
6
...
ARGS *m_args = (ARGS*)p_Args;
CEnsureCloseFile hFileSrc = CreateFile(m_args->pszFileSrc, GENERIC_READ,
         FILE_SHARE_READ, NULL, OPEN_EXISTING, 
         FILE_FLAG_NO_BUFFERING | FILE_FLAG_OVERLAPPED, NULL);
...
После вызова данной функции данные структуры m_args изменяются на черте что.

Но если сделать вот так:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
ARGS *m_args = (ARGS*)p_Args;
 
   TCHAR szPathname[_MAX_PATH];
   TCHAR szSavePathname[_MAX_PATH];
   TCHAR szRenamePathname[_MAX_PATH];
   HWND m_hwnd = m_args->m_test;
   HWND m_MainHwnd = m_args->m_Main;
 
   _stprintf(szPathname, _T("%s"), m_args->pszFileSrc);
   _stprintf(szSavePathname, _T("%s"), m_args->pszFileDst);
 
   CEnsureCloseFile hFileSrc = CreateFile(szPathname, GENERIC_READ,
         FILE_SHARE_READ, NULL, OPEN_EXISTING, 
         FILE_FLAG_NO_BUFFERING | FILE_FLAG_OVERLAPPED, NULL);
И работать уже с переменными внутри функции потока - то данные структуры разрушаются, а переменные остаются.

Может я туплю и так должно быть? Или пора заново книжки читать по WinAPI и MSDN старенький от MSVC++ 6.0 перечитывать?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
07.09.2019, 09:49
Ответы с готовыми решениями:

Странное поведение при передаче параметров
Имеется некое окно, в котором есть некая таблица. В модель таблицы, в качестве значений передается ArrayList<Class_1> list1. ...

Странное поведение в Bash при передаче float аргумента программе
Добрый день. Столкнулся с такой проблемой в Debian Linux 10.1. В шелле Bash на macOS Catalina 10.15.2 такой проблемы не было вообще. ...

Ошибка сокета при передаче в поток
Короче лаба по програмиированию, типа сервер на TCP сокетах. Ошибка возникает внутри потока, куда я передаю созданные аксептом сокеты на...

7
Maniac
Эксперт С++
 Аватар для ISergey
1464 / 965 / 160
Регистрация: 02.01.2009
Сообщений: 2,820
Записей в блоге: 1
07.09.2019, 10:23
Цитата Сообщение от ids1488 Посмотреть сообщение
После вызова данной функции данные структуры m_args изменяются на черте что
как создаете поток и передаете структуру?

К примеру
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
struct ARGS
{
    TCHAR pszFileSrc[MAX_PATH];
    TCHAR pszFileDst[MAX_PATH];
    HWND m_test;
    HWND m_Main;
};
 
 
 
int main(){
 
    ...
    
    {
        ARGS arg = {..};
        CreateThread(.., threadFunc, &arg, ..);
        
    }
    
    // Здесь arg уже не существует (тоесть на стеке может быть уже затерто)
}
Должно повторить вашу ошибку.

Попробуйте так
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int main(){
 
    ...
    
    {
        ARGS *arg = new ARGS;
        //заполнение arg 
        ....
        CreateThread(.., threadFunc, arg, ..);
        
    }
    
    // arg существует пока сами не удалим
}
 
DWORD WINAPI threadFunc(LPVOID lpParam)
{
    ARGS* arg = (ARGS*) lpParam;
    
    ...
    
    detele arg;
}
1
0 / 0 / 0
Регистрация: 07.09.2019
Сообщений: 5
07.09.2019, 12:41  [ТС]
Цитата Сообщение от ISergey Посмотреть сообщение
Должно повторить вашу ошибку.
Так и делаю. Вы правы.

Цитата Сообщение от ISergey Посмотреть сообщение
Попробуйте так
Попробовал. На Windows 7 (там где и будет работать программа) все корректно. А на Windows 10 (Version 10.0.18362.267) в отладчике VS та же ситуация.

Цитата Сообщение от ISergey Посмотреть сообщение
detele arg;
А разве при вызове из потока ExitThread(-1) не уничтожаются все данные потока? Или лучше самому явно удалить?
0
Maniac
Эксперт С++
 Аватар для ISergey
1464 / 965 / 160
Регистрация: 02.01.2009
Сообщений: 2,820
Записей в блоге: 1
07.09.2019, 12:54
Цитата Сообщение от ids1488 Посмотреть сообщение
А разве при вызове из потока ExitThread(-1) не уничтожаются все данные потока? Или лучше самому явно удалить?
стек почистится, а та память что выделена динамически будет просто висеть в памяти пока все приложение не умрет.

Все что выделяется через new/malloc должно быть освобождено вами когда больше не нужно функциями delete/free

А на Windows 10 (Version 10.0.18362.267) в отладчике VS та же ситуация.
показывайте как создается поток и подготавливаются даные перед запуском потока.
1
0 / 0 / 0
Регистрация: 07.09.2019
Сообщений: 5
07.09.2019, 13:03  [ТС]
Цитата Сообщение от ISergey Посмотреть сообщение
показывайте как создается поток и подготавливаются даные перед запуском потока.
C++
1
2
3
4
5
6
7
8
ARGS *m_args = new ARGS;
_stprintf(m_args->pszFileSrc, _T("%s"), szPathname);
 _stprintf(m_args->pszFileDst, _T("%s"), szSavePathname);
m_args->m_test = GetDlgItem(hWnd, IDC_PROGRESS1);
m_args->m_Main = hWnd;
 
DWORD dwThreadID;
g_nThread = CreateThread(0,0,(LPTHREAD_START_ROUTINE)FileCopy, &m_args,0, &dwThreadID);

И на delete вылетает в Exception.
0
Maniac
Эксперт С++
 Аватар для ISergey
1464 / 965 / 160
Регистрация: 02.01.2009
Сообщений: 2,820
Записей в блоге: 1
07.09.2019, 14:55
Здесь
C++
1
_nThread = CreateThread(0,0,(LPTHREAD_START_ROUTINE)FileCopy, &m_args,0, &dwThreadID)
Перед m_args лишний &.
1
0 / 0 / 0
Регистрация: 07.09.2019
Сообщений: 5
07.09.2019, 15:58  [ТС]
Цитата Сообщение от ISergey Посмотреть сообщение
Перед m_args лишний &.
Это то понятно. Скопировал из cpp из блокнота, а не из VS.

Но все равно вот во что превращаются элементы структуры, когда вызывается первый CreateFile(...):

pszFileSrc = 0x07411208 L"ĥ罨ܾDB\\adb.exe"
pszFileDst = 0x07411410 L"C:\\DOCS\\adb.exe"
m_test = 0x000709aa {unused=??? }
m_Main = 0x000709e4 {unused=??? }

А значения до вызова (сразу по старте потока):

(m_args)->pszFileSrc 0x07411208 L"C:\\ADB\\adb.exe"
(m_args)->pszFileDst 0x07411410 L"C:\\DOCS\\adb.exe._FULL.bin"
m_args->m_test = 0x000709aa {unused=??? }
m_args->m_Main = 0x000709e4 {unused=??? }

Интересная закономерность: в Windows 7 + MSVS 6.0 все норм. В Windows 10 + MSVS 2015 Pro такая фигня. Уже не знаю на что грешить. Толи на винду с торрента, то ли на MSVS оттуда же.

По идее же CreateFile() не вносит изменения в переменную с именем файла. Не должен по крайней мере.
0
0 / 0 / 0
Регистрация: 07.09.2019
Сообщений: 5
08.09.2019, 20:29  [ТС]
Все. Разобрался.

Выкинул заголовок с переопределениями функций и макросов от Рихтера и реализовал все штатными средствами Win API. Все корректно работает.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
08.09.2019, 20:29
Помогаю со студенческими работами здесь

Странное поведение ПК при старте
Всем привет!Во время запуска пк,кулера гаснут,изображения нету.Все это длится 1-2 секунды и происходит нормальный запуск после этого.Что...

Странное поведение при отладке
Здравствуйте. Решил написать небольшую тулзу и столкнулся с проблемой: скомпилированный код прекрасно работает в отладчике, однако не...

Странное поведение при загрузке
Доброго времени суток! Ситуация такая,Имеется материнка ASUS P8P67 rev. B3 четыре планки памяти две Kingston 2xKHX1600C9D3/2GX и Kingston...

Странное поведение при буте
помогите разобраться. комп старенький достаточно, при включение питания пишет cmos checksum error(батарейка недавно менялась, дата не...

Странное поведение при делегировании
Доброй ночи, Господа. Пишу некую доп. функциональность к календарю, но дело, собственно, не в этом. Прописываю 2 события. Т.к....


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

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru