Вопрос о правильном пути к файлу - PullRequest
2 голосов
/ 15 ноября 2010

Я использую следующий код для создания файла, но он всегда терпел неудачу с кодом ошибки 123 (синтаксис пути недопустим).

Странная вещь: path_ok всегда в порядке, но path_err всегда терпел неудачу с 123. И после сбоя буфер, на который path_err указывает очищено.

Может ли кто-нибудь пролить свет на меня? Я проверил память двух указателей, и их содержимое кажется идентичным.

Большое спасибо.

 WCHAR *pDumpFileName = ComposeDumpFileName();
 WCHAR *path_ok = _T("d:\\myapp_Utopia_2010-11-15_04-22-05.dmp");
 WCHAR *path_err = pDumpFileName;
 ::wprintf(pDumpFileName);
 HANDLE hFile = ::CreateFileW( pDumpFileName, GENERIC_READ | GENERIC_WRITE, 
  0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); 

Функция ComposeDumpFileName () выглядит следующим образом:

WCHAR* ComposeDumpFileName(void)
{
 // get the time
    SYSTEMTIME sys_time;
    ::GetSystemTime(&sys_time);

    // get the computer name
    WCHAR computer_name[MAX_COMPUTERNAME_LENGTH + 1];
    DWORD computer_name_len = ARRAYSIZE(computer_name);
 ::GetComputerNameW(computer_name, &computer_name_len);

    // build the filename: APPNAME_COMPUTERNAME_DATE_TIME.DMP
    WCHAR dump_file_path[MAX_PATH];

 ::swprintf_s(dump_file_path, ARRAYSIZE(dump_file_path), 
        _T("d:\\myapp_%s_%04u-%02u-%02u_%02u-%02u-%02u.dmp"), 
        computer_name, sys_time.wYear, sys_time.wMonth, sys_time.wDay,
        sys_time.wHour, sys_time.wMinute, sys_time.wSecond);

 return dump_file_path;
}

Обновление

В моем коде выше, когда я выполняю следующий код:

WCHAR *pDumpFileName = ComposeDumpFileName();

После возвращения ComposeDumpFileName его кадр стека является недействительным, однако его локальная переменная WCHAR dump_file_path [MAX_PATH] все еще существует в стеке. Таким образом, это объясняет, почему я все еще вижу его содержимое, хотя пространство стека для него уже недопустимо.

Затем я выполняю следующую инструкцию:

     ::wprintf(pDumpFileName);
     HANDLE hFile = ::CreateFileW( pDumpFileName, GENERIC_READ | GENERIC_WRITE, 
      0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); 

wprintf () и CreateFileW () имеют свои собственные стековые фреймы. Хотя в отладчике я обнаружил, что стековый фрейм wprintf () не уничтожает содержимое памяти, указанное pDumpFileName , может иметь CreateFileW, поэтому он жалуется на недопустимый синтаксис пути.

Это мое текущее понимание, пожалуйста, поправьте меня, если я ошибаюсь.

Спасибо.

1 Ответ

16 голосов
/ 15 ноября 2010

Одна основная проблема с вашим кодом - это буфер, который вы возвращаете, находится в стеке, и это большой нет, нет:

 // build the filename: APPNAME_COMPUTERNAME_DATE_TIME.DMP 
 WCHAR dump_file_path[MAX_PATH]; 

Либо измените его на статический:

 // build the filename: APPNAME_COMPUTERNAME_DATE_TIME.DMP 
 static WCHAR dump_file_path[MAX_PATH]; 

или передайте буфер в функцию.

...