First-chance exception at 0x77983AB3 (ntdll.dll) in binary.exe: 0xC0000005: Access violation reading location 0x6F726369.
First-chance exception at 0x7650C41F in binary.exe: Microsoft C++ exception: std::bad_alloc at memory location 0x003DF0DC.
First-chance exception at 0x7650C41F in binary.exe: Microsoft C++ exception: std::bad_alloc at memory location 0x003DF0DC.
First-chance exception at 0x77983AB3 (ntdll.dll) in binary.exe: 0xC0000005: Access violation reading location 0x6F726369.
First-chance exception at 0x7650C41F in binary.exe: Microsoft C++ exception: std::bad_alloc at memory location 0x003DEA40.
First-chance exception at 0x7650C41F in binary.exe: Microsoft C++ exception: std::bad_alloc at memory location 0x003DEA40.
First-chance exception at 0x7650C41F in binary.exe: Microsoft C++ exception: [rethrow] at memory location 0x00000000.
First-chance exception at 0x7650C41F in binary.exe: Microsoft C++ exception: [rethrow] at memory location 0x00000000.
Unhandled exception at at 0x7650C41F in binary.exe: Microsoft C++ exception: std::bad_alloc at memory location 0x003DEA40.
The program '[7632] binary.exe' has exited with code 0 (0x0).
我不知道自己是否犯了新手错误,但是每次尝试运行下面的代码时,都会得到上面列出的错误-通过各种论坛帖子和错误消息收集的信息,我发现了一个问题内存的分配,但是据我所知。
下面列出的代码是我项目的简化版本,因为源文件很长,因此实际上不需要发布。
int _tmain(int argc, _TCHAR* argv[])
{
check(true);
system("pause");
return 0;
}
int check(bool initialCheck)
{
char* path = getDocumentRootA(); strcat(path, "Test//file.test");
char* filePathA = getDocumentRootA(); strcat(filePathA, "Test2\\file.test");
char* filePathB = getDocumentRootA(); strcat(filePathB, "Test3\\file.test");
cout << "Checking if files exists...";
if (doesFileExist(path) == true)
{
cout << "Yes\n";
} else if (doesFileExist(path) == false) {
cout << "No\n"; // todo
}
cout << "Checking if other files exist...";
if (doesFileExist(filePathA) == true && doesFileExist(filePathB) == true)
{
cout << "Yes\n";
}
return 0;
}
char* getDocumentRootA()
{
CHAR documentRootC[MAX_PATH]; CA2W uDocumentRoot(documentRootC);
HRESULT result = SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, uDocumentRoot); CW2A documentRoot_T(uDocumentRoot); strcat(documentRoot_T, "\\");
string documentRootTemp = documentRoot_T; char* documentRoot = const_cast<char*>(documentRootTemp.c_str());
cout<<documentRoot;
return documentRoot;
}
可能还值得注意的是,我试图更改代码的第一部分(请参见下面的示例),以便
getDocumentRootA()
函数仅被调用一次,但是并不能解决问题。char* testvar = getDocumentRootA();
char* path = testvar; strcat(path, "Microsoft\\file.test");
char* filePathA = testvar; strcat(filePathA, "Windows\\AppLoc\\file.test");
char* filePathB = testvar; strcat(filePathB, "Windows\\U\\file.test");
最佳答案
在getDocumentRootA()
中,您正在重新调整指向堆栈分配对象的成员变量的指针,这很不好,因为一旦离开该函数,它将被清除。更糟糕的是,由于您不应该修改string
的内部成员,因此存在两个问题:
string documentRootTemp = documentRoot_T;
^^^^^^
Object on the stack
char* documentRoot = const_cast<char*>(documentRootTemp.c_str());
^^^^^^
Pointer to said object
return documentRoot;
^^^^^
Returning said pointer
这是您使用该指针的位置:
char* path = getDocumentRootA();
strcat(path, "Test//file.test");
^^^^
Modifying pointer to object that does not exist anymore
您可能应该只从
std::string
返回GetDocumentRootA()
,然后在需要check
的位置使用c_str
返回const char *
。您可以使用+=
运算符将char *
附加到std::string
,请参阅此reference。这是一个非常基本的示例,使我的建议更具体:#include <string>
#include <iostream>
std::string getDocumentRootA()
{
std::string str( "Path//") ;
return str ;
}
bool doesFileExist( const char *p )
{
bool ret = false ;
// Do checking here
return ret ;
}
int main()
{
std::string str2( getDocumentRootA() ) ;
str2 += "Test//file.test" ;
std::cout << str2.c_str() << std::endl ;
if( doesFileExist( str2.c_str() ))
{
std::cout << "Yes" << std::endl ;
}
else
{
std::cout << "No" << std::endl ;
}
}