2016-10-18 3 views
0

Я запускаю приложение Visual C++ MFC в режиме выпуска. Я собираю все, используя Visual Studio 2010.Указатель объекта случайным образом указывает на 0x00000

Мое приложение запускает мини-станцию ​​с ЧПУ через USB VCP-связь.

У меня есть файл XML, в котором хранятся настройки приложения.

Моя проблема заключается в следующем: ocassionaly (и это повторяемо) указатель на tinyxml2 :: XMLDocument, который я использую, устанавливается в 0x000.

Информация:

Иногда файл XML пишутся в то время как мельница работает.

Перед тем, как произошла ошибка, мельница, в которой я запускаю siezes почти 30 секунд.

Я использую блокировки мьютекса, чтобы убедиться, что xmldoc не записывается дважды в файл.

Замки мьютексов работают, и ошибка мьютекса никогда не возникает. Я знаю, что код мьютекса не идеален, но это не проблема. Честный.

Я никогда не пишу в указатель xmldoc, кроме случаев, когда родительский класс загружается.

И вдруг внезапно указатель xmlDoc устанавливается в ноль.

Любые мысли кто-нибудь?

Вот моя экономия кода, хотя проблема может лежать в другом месте:

void XMLSettings::SaveToXML() 
{ 
    HANDLE g_Mutex = CreateMutex(NULL, TRUE, "XMLSavingMutex"); 
    DWORD wait_success = WaitForSingleObject(g_Mutex, 30000L); 
    if(wait_success == WAIT_OBJECT_0){ 
     CIsoProApp* pApp = (CIsoProApp*)AfxGetApp(); 
     if(PathFileExists(pApp->DrivePath + "IsoPro\\temp.xml")) 
     { 
      DeleteFile(pApp->DrivePath + "IsoPro\\temp.xml"); 
     } 

     if(0==&xmlDoc) 
     { 
      OutputDebugString("xmlDoc == NULL"); 
     } 

     int errorcode = xmlDoc->SaveFile(pApp->DrivePath + "IsoPro\\temp.xml"); 

     if(errorcode != 0) 
     { 
      OutputDebugString("xmlDoc == errorcode"); 
     } 

     if(0==&xmlDoc) 
     { 
      OutputDebugString("xmlDoc == NULL2"); 
     } 

     if(0==xmlDoc) 
     { 
      OutputDebugString("xmlDoc == NULL"); 
     } 

     if(PathFileExists(pApp->DrivePath + "IsoPro\\Settings.xml")) 
     { 
      DeleteFile(pApp->DrivePath + "IsoPro\\Settings.xml"); 
     } 
     MoveFile(pApp->DrivePath + "IsoPro\\temp.xml",pApp->DrivePath + "IsoPro\\Settings.xml"); 
     ReleaseMutex(g_Mutex); 
    } 
    else 
    { 
     int errorInt = GetLastError(); 
     CString error; 
     error.Format("%d",errorInt); 
     if(errorInt != ERROR_ALREADY_EXISTS) 
     { 
      AfxMessageBox("XMLSavingMutex Error. WaitSuccess = " + wait_success); 
      AfxMessageBox("XMLSavingMutex Error. GetLastError = " + error); 
     } 
    } 
    CloseHandle(g_Mutex); 
} 
+3

Если у вас несколько потоков, вызывающих 'SaveToXML', возможно, вы должны сделать mutex' static'. Кроме того, какую версию визуальной студии вы используете? Здесь мы можем использовать более стандартизованные функции синхронизации потоков. – AndyG

+0

Как сказал AndyG - вы не хотите создавать/уничтожать мьютексы, вам нужен один экземпляр, который вы блокируете и разблокируете. – UKMonkey

+1

Вы можете настроить точку останова данных в Visual Studio. Таким образом, вы можете найти, когда ваш указатель окажется недействительным. – Ari0nhh

ответ

1

Так как кажется, что вы создаете мьютекс каждый разSaveToXML называется, вы должны изменить свой призыв к

HANDLE g_Mutex = CreateMutex(NULL, FALSE, "XMLSavingMutex"); 

Выполнение этого приведет к созданию именованного мьютекса, который позволяет реализации диктовать, кто является владельцем; другие потоки получат один и тот же мьютекс.

От doc:

Два или несколько процессов могут назвать CreateMutex создать такой же имя семафора. Первый процесс фактически создает мьютекс, а последующие процессы с достаточными правами доступа просто открывают дескриптор существующего мьютекса. Это позволяет нескольким процессам получать дескрипторы одного и того же мьютекса, освобождая пользователя от обязанности гарантировать, что процесс создания будет запущен в первую очередь. При использовании этого метода вы должны установить флаг bInitialOwner в FALSE; В противном случае может быть трудно убедиться, какой процесс имеет первоначальное владение.

(Кредит WhozCraig для указывая именованные семафоры)

+0

Если я ошибаюсь, процедура WaitForSingleObject позволяет нескольким мьютексам запускать «синхронизированный» код. Я что-то пропустил? –

+0

'WaitForSingleObject' будет пытаться заблокировать мьютексы. Если каждый поток имеет свой собственный мьютекс, тогда нет смысла. – AndyG

+0

@DanG: Существует также вероятность того, что ошибка в коде, который вы еще не показали нам. Я уверен, что 'xmlDoc' передается и используется в других контекстах, чем это. – AndyG

0

Оказывается, что я был доступ к XML-поглотитель при написании XML в файл. Я установил единый блокировку мьютекса для всех действий xml, и кажется, что они функционируют должным образом. Спасибо всем за помощь. Я свяжусь с дополнительной информацией, если она станет доступной.

Смежные вопросы