.c_str() 未按预期运行

.c_str() doesn't behave as expected

我想创建一个进程来读取一些串口。但是,用户将来应该能够更改程序所在的路径。这就是为什么我想包含变量 BasePathFile,它在 class 的初始化过程中设置为默认值:

const std::string BP = "C:\aerospec_developement\";
...
BasePathFile = BP;
...

谁能解释一下为什么 //1 不起作用,但 //2 没问题

void AerospecGUI::ReadPressure()
{
//1 const char *Args = ("C:\Windows\System32\cmd.exe /C powershell /C "+ BasePathFile+"sourcecode\pressure.ps1 -comport COM4 -baud 1200 -parity None -data 8 -stopbits one").c_str();
//2 const char *Args = "C:\Windows\System32\cmd.exe /C powershell /C C:\aerospec_developement\sourcecode\pressure.ps1 -comport COM4 -baud 1200 -parity None -data 8 -stopbits one";

STARTUPINFO StartupInfo;
PROCESS_INFORMATION ProcessInfo;
memset(&StartupInfo, 0, sizeof(StartupInfo));
memset(&ProcessInfo, 0, sizeof(ProcessInfo));
StartupInfo.cb = sizeof(StartupInfo);
wchar_t wargs[1000];
mbstowcs(wargs, Args, strlen(Args)+1);//Plus null
LPWSTR argsptr = wargs;

bool result = CreateProcess(NULL, argsptr, NULL, NULL, FALSE, NULL, NULL, NULL,
                             &StartupInfo, &ProcessInfo);
...

此外,作者在另一个函数中写了一个非常相似的行。但是这个有效。

bool AerospecGUI::FTP(std::string command, std::string file)
{
// This function executes a batch script with the given parameters. The batch script
// generates a .ftp file which contains the commands to perform the action given by "command"
// (get, put, delete).
const char *Args = ("C:\Windows\System32\cmd.exe /C "+BasePathFile +"FTP\FileTransfer.bat " + ServerURL + " root password " + command + " " + BasePathFile + "FTP\ " + file +" " + BasePathFile + "FTP\" + file.substr(0,file.size()-4)+".ftp").c_str();
STARTUPINFO StartupInfo;
PROCESS_INFORMATION ProcessInfo;
memset(&StartupInfo, 0, sizeof(StartupInfo));
memset(&ProcessInfo, 0, sizeof(ProcessInfo));
StartupInfo.cb = sizeof(StartupInfo);
wchar_t wargs[1000];
mbstowcs(wargs, Args, strlen(Args)+1);//Plus null
LPWSTR argsptr = wargs;
...

对于1,您创建一个临时 std::string 对象,并获取指向其内部字符串的指针。一旦临时对象被破坏,字符串将不复存在,指针将不会指向任何有效的地方。

对于 2 你有一个实际的常量字符串文字,它有程序的生命周期并且永远不会停止存在。

这似乎对你的第二个例子有用只是侥幸。杂散的无效指针是未定义的行为,有时这些行为似乎工作得很好。

1和原作者代码是错误的:c_str() returns一个类C字符串的指针,但是它是std::stringclass(参见 docs)。在 std::string 对象过期后取消引用其指针是未定义的行为(可能有效也可能无效)。

2 工作正常

const char *Args = "C:\... one";

因为它是一个字符串文字,并且它的生命周期跨越整个程序执行。