有关有效文件路径的问题

smw*_*dia 2 c windows createfile

我使用以下代码创建一个文件,但它始终失败,错误代码为123(路径语法无效).

奇怪的是:path_ok总是正常,但path_err总是以123失败.在失败之后,path_err指向的缓冲区被清除.

谁能对我有所了解?我检查了2个指针的内存,它们的内容似乎是相同的.

非常感谢.

 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 ); 
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

更新

在上面的代码中,当我执行以下代码时:

WCHAR *pDumpFileName = ComposeDumpFileName();
Run Code Online (Sandbox Code Playgroud)

返回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 ); 
Run Code Online (Sandbox Code Playgroud)

wprintf()和CreateFileW()有自己的堆栈帧.虽然在调试器中,我发现wprintf()的堆栈帧没有破坏pDumpFileName指向的内存内容,CreateFileW可能有,所以它抱怨路径语法无效.

这是我目前的理解,如果我错了,请纠正我.

谢谢.

jus*_*sij 16

您的代码的一个主要问题是您返回的缓冲区是否在堆栈中,这是一个很大的问题:

 // build the filename: APPNAME_COMPUTERNAME_DATE_TIME.DMP 
 WCHAR dump_file_path[MAX_PATH]; 
Run Code Online (Sandbox Code Playgroud)

要么将其更改为静态:

 // build the filename: APPNAME_COMPUTERNAME_DATE_TIME.DMP 
 static WCHAR dump_file_path[MAX_PATH]; 
Run Code Online (Sandbox Code Playgroud)

或者将缓冲区传递给函数.

  • 你确实可以使用malloc并只返回指向malloc'ed缓冲区的指针.但是一旦完成它,不要忘记释放缓冲区,否则最终会导致内存泄漏. (2认同)
  • "这个小虫不是一个棘手的问题吗?" - 这些类型的错误很难追踪,但通常只需阅读代码就可以很容易地找到它们.秘诀是使用{}作为指导.简单的规则是在{匹配后将未声明}之后声明的任何事物.这些大括号字符定义了为其定义变量的"范围". (2认同)