.c_str()的行为不如预期

问题描述:

我想创建一个读取某些串行端口的进程。但是用户应该能够改变程序未来的路径。这就是为什么我想包括可变BasePathFile,它被设置为默认值都灵类的初始化:.c_str()的行为不如预期

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; 
... 
+0

什么是'BasePathFile'?它是一个'std :: string'吗? –

+0

'c_str()'提供的指针只对'std :: string'实例的生命周期有效。所以如果你有一个temparary的'std :: string'实例,指针在该语句后不再有效。 –

+0

这是不可读的! –

1和原作者的代码是错误的:c_str()返回一个指向一个C类的字符串,但它是std::string类的成员函数(见docs)。在std::string对象已过期后取消引用其指针是未定义的行为(可能或可能不起作用)。

2正常工作,而不是

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

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

+0

谢谢你的回答! – andreasjoerg

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

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

这似乎是为你的第二个例子工作只是一个侥幸。你有什么与流浪无效指针是未定义的行为有时这些似乎工作得很好。

+0

非常感谢你 – andreasjoerg