当我将承诺分配给线程时,C++ 获得 "Debug Error R6010 -abort() has been called "
C++ Getting "Debug Error R6010 -abort() has been called " when i assign promises to threads
我遇到错误:Debug Error R6010 -abort() has been called
在我的代码中:
bool ListFiles(wstring path, wstring mask, vector<wstring>& files) {
HANDLE hFind = INVALID_HANDLE_VALUE;
WIN32_FIND_DATA ffd;
wstring spec;
stack<wstring> directories;
directories.push(path);
files.clear();
while (!directories.empty()) {
path = directories.top();
spec = path + L"\" + mask;
directories.pop();
hFind = FindFirstFile(spec.c_str(), &ffd);
if (hFind == INVALID_HANDLE_VALUE) {
return false;
}
do {
if (wcscmp(ffd.cFileName, L".") != 0 && wcscmp(ffd.cFileName, L"..") != 0) {
if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
directories.push(path + L"/" + ffd.cFileName);
}
else {
files.push_back(path + L"/" + ffd.cFileName);
}
}
} while (FindNextFile(hFind, &ffd) != 0);
if (GetLastError() != ERROR_NO_MORE_FILES) {
FindClose(hFind);
return false;
}
FindClose(hFind);
hFind = INVALID_HANDLE_VALUE;
}
return true;}
void findText(std::string filename, std::string word , promise<string> &prom) {
std::ifstream f(filename);
std::string s;
std::string notFound = "no";
bool found = false;
if (!f) {
std::cout << "il file non esiste"<<std::endl;
}
while (f.good()) {
std::getline(f, s);
if (s.find(word, 0) != string::npos) {
found = true;
}
}
if (found) {
//cout << "Parola trovata in -> " << filename << endl;
prom.set_value_at_thread_exit(filename);
}
else {
prom.set_value_at_thread_exit(notFound);
}
f.close();}
int main(int argc, char* argv[]){
//vector<std::thread> th;
vector<future<string>> futures;
vector<wstring> files;
string search = "ciao";
string notFound = "no";
if (ListFiles(L"pds", L"*", files)) {
for (vector<wstring>::iterator it = files.begin(); it != files.end(); ++it) {
//wcout << it->c_str() << endl;
wstring ws(it->c_str());
string str(ws.begin(), ws.end());
// Show String
//cout << str << endl;
//Creo una promise per ogni thread in cui andrò a cercare il risulato
std::promise<string> prom;
futures.push_back(prom.get_future());
std::thread(findText,str,search,std::ref(prom)).detach();
}
}
for (int i = 0; i < futures.size(); i++){
futures.at(i).wait();
if (futures.at(i).get().compare(notFound)!=0)
cout << "Parola trovata in ->" <<futures.at(i).get()<<endl;
}
return 0;}
我之前尝试过不使用 promises 并让每个线程在找到 word 并且有效时打印文件名。
所以我不知道为什么使用 promises 和 future 来检索这个值会导致我出现这个问题......
我正在使用 VS 2013
让我们仔细看看这些行:
for (...) {
...
std::promise<string> prom;
...
std::thread(findText,str,search,std::ref(prom)).detach();
}
首先创建一个局部变量 prom
,然后将对该变量的引用传递给线程。
这个问题是一旦循环迭代,变量prom
就会超出范围并且对象被破坏。您曾经拥有的参考资料不再有任何参考资料。使用引用将导致未定义的行为。
所以解决办法是不使用引用(或指向prom
变量的指针),这会导致问题,因为std::promise
无法复制。但是,它可以移动:
std::thread(findText,str,search,std::move(prom)).detach();
为此,您可能需要让线程函数将 promise 参数作为右值引用:
void findText(std::string filename, std::string word , promise<string> &&prom) {
...
}
如果上述解决方案不起作用,那么您可以使用新的 C++11 智能指针进行动态分配,例如 std::unique_ptr
。
那么线程函数应该按值取智能指针,比如
void findText(std::string filename, std::string word , std::unique_ptr<std::promise<string>> prom) {
...
}
然后你创建线程就像
auto prom = std::make_unique<std::promise<std::string>>();
// Or if you don't have std::make_unique
// std::unique_ptr<std::promise<std::string>> prom(new std::promise<std::string>);
futures.push_back(prom->get_future();
std::thread(findText,str,search,std::move(prom)).detach();
记得在你的线程函数(findText
)中变量prom
是一个指针并且在使用的时候需要使用箭头运算符,比如
prom->set_value_at_thread_exit(filename);
// ^^
// Note "arrow" operator here
我遇到错误:Debug Error R6010 -abort() has been called
在我的代码中:
bool ListFiles(wstring path, wstring mask, vector<wstring>& files) {
HANDLE hFind = INVALID_HANDLE_VALUE;
WIN32_FIND_DATA ffd;
wstring spec;
stack<wstring> directories;
directories.push(path);
files.clear();
while (!directories.empty()) {
path = directories.top();
spec = path + L"\" + mask;
directories.pop();
hFind = FindFirstFile(spec.c_str(), &ffd);
if (hFind == INVALID_HANDLE_VALUE) {
return false;
}
do {
if (wcscmp(ffd.cFileName, L".") != 0 && wcscmp(ffd.cFileName, L"..") != 0) {
if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
directories.push(path + L"/" + ffd.cFileName);
}
else {
files.push_back(path + L"/" + ffd.cFileName);
}
}
} while (FindNextFile(hFind, &ffd) != 0);
if (GetLastError() != ERROR_NO_MORE_FILES) {
FindClose(hFind);
return false;
}
FindClose(hFind);
hFind = INVALID_HANDLE_VALUE;
}
return true;}
void findText(std::string filename, std::string word , promise<string> &prom) {
std::ifstream f(filename);
std::string s;
std::string notFound = "no";
bool found = false;
if (!f) {
std::cout << "il file non esiste"<<std::endl;
}
while (f.good()) {
std::getline(f, s);
if (s.find(word, 0) != string::npos) {
found = true;
}
}
if (found) {
//cout << "Parola trovata in -> " << filename << endl;
prom.set_value_at_thread_exit(filename);
}
else {
prom.set_value_at_thread_exit(notFound);
}
f.close();}
int main(int argc, char* argv[]){
//vector<std::thread> th;
vector<future<string>> futures;
vector<wstring> files;
string search = "ciao";
string notFound = "no";
if (ListFiles(L"pds", L"*", files)) {
for (vector<wstring>::iterator it = files.begin(); it != files.end(); ++it) {
//wcout << it->c_str() << endl;
wstring ws(it->c_str());
string str(ws.begin(), ws.end());
// Show String
//cout << str << endl;
//Creo una promise per ogni thread in cui andrò a cercare il risulato
std::promise<string> prom;
futures.push_back(prom.get_future());
std::thread(findText,str,search,std::ref(prom)).detach();
}
}
for (int i = 0; i < futures.size(); i++){
futures.at(i).wait();
if (futures.at(i).get().compare(notFound)!=0)
cout << "Parola trovata in ->" <<futures.at(i).get()<<endl;
}
return 0;}
我之前尝试过不使用 promises 并让每个线程在找到 word 并且有效时打印文件名。 所以我不知道为什么使用 promises 和 future 来检索这个值会导致我出现这个问题...... 我正在使用 VS 2013
让我们仔细看看这些行:
for (...) {
...
std::promise<string> prom;
...
std::thread(findText,str,search,std::ref(prom)).detach();
}
首先创建一个局部变量 prom
,然后将对该变量的引用传递给线程。
这个问题是一旦循环迭代,变量prom
就会超出范围并且对象被破坏。您曾经拥有的参考资料不再有任何参考资料。使用引用将导致未定义的行为。
所以解决办法是不使用引用(或指向prom
变量的指针),这会导致问题,因为std::promise
无法复制。但是,它可以移动:
std::thread(findText,str,search,std::move(prom)).detach();
为此,您可能需要让线程函数将 promise 参数作为右值引用:
void findText(std::string filename, std::string word , promise<string> &&prom) {
...
}
如果上述解决方案不起作用,那么您可以使用新的 C++11 智能指针进行动态分配,例如 std::unique_ptr
。
那么线程函数应该按值取智能指针,比如
void findText(std::string filename, std::string word , std::unique_ptr<std::promise<string>> prom) {
...
}
然后你创建线程就像
auto prom = std::make_unique<std::promise<std::string>>();
// Or if you don't have std::make_unique
// std::unique_ptr<std::promise<std::string>> prom(new std::promise<std::string>);
futures.push_back(prom->get_future();
std::thread(findText,str,search,std::move(prom)).detach();
记得在你的线程函数(findText
)中变量prom
是一个指针并且在使用的时候需要使用箭头运算符,比如
prom->set_value_at_thread_exit(filename);
// ^^
// Note "arrow" operator here