我正在尝试使用简单的线性方法实现优先级队列,如Art of Multiprocessor programming中所述。我是c ++的新手并且难以排除故障。
我已经实现了两个模板类,并使用简单的测试方法对它们进行测试。由于我无法确定错误,我将以下三个类别粘贴以供参考。
我知道_M_ construct null not valid
在尝试使用nullptr
构建字符串时会出现,但我不知道我在做什么。
创建的三个类如下:
#include <mutex>
#include <deque>
#include <memory>
#include <iostream>
using namespace std;
namespace priority
{
template<typename T>
class Bin
{
private:
std::deque<T> v;
std::mutex m;
public:
Bin() {
}
Bin(const Bin &o) {
}
const Bin &operator=(const Bin &other) {
return *this;
}
void put(T item) {
std::lock_guard<std::mutex> lock(m);
v.push_back(item);
}
T *get() {
std::lock_guard<std::mutex> lock(m);
if (v.size() == 0) {
return nullptr;
}
else {
T val = v.front();
T *ptr_val = &(val);
v.pop_front();
return ptr_val;
}
}
bool isEmpty() {
std::lock_guard<std::mutex> lock(m);
return v.size() == 0;
}
};
}
#include <mutex>
#include <vector>
#include <memory>
#include "Bin.h"
namespace priority
{
template<typename T>
class SimpleLinear
{
private:
int range;
std::vector<Bin<T>> pqueue;
public:
SimpleLinear(int range){
this->range = range;
for (int i = 0; i < range; i++)
{
pqueue.push_back(Bin<T>());
}
}
void add(T item, int key) {
pqueue[key].put(item);
}
T removeMin() {
for (int i = 0; i < range; i++)
{
T *item = pqueue[i].get();
if (item != nullptr) {
return *item;
}
}
return nullptr;
}
};
}
#include <iostream>
#include <vector>
#include <thread>
#include <algorithm>
#include "SimpleLinear.h"
using namespace std;
using namespace priority;
void te(SimpleLinear<string> s, int thread_id) {
s.add("sundar"+to_string(thread_id), thread_id);
s.add("akshaya"+to_string(thread_id), 3);
s.add("anirudh"+to_string(thread_id), 1);
s.add("aaditya"+to_string(thread_id), 5);
cout << s.removeMin() << endl;
cout << s.removeMin() << endl;
cout << s.removeMin() << endl;
}
int main(int argc, char const *argv[])
{
SimpleLinear<string> s(100);
std::vector<std::thread> v;
for (int i = 0; i < 100; i++)
{
// if (i % 2 == 0)
v.push_back(thread(te, std::ref(s), i));
// else
// v.push_back(thread(t, std::ref(s), i));
}
for_each(v.begin(), v.end(), std::mem_fn(&std::thread::join));
return 0;
}
我收到了错误:
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_M_construct null not valid
terminate called recursively
terminate called recursively
terminate called recursively
Aborted (core dumped)
答案 0 :(得分:3)
崩溃的一个原因是SimpleLinear<T>::removeMin
当T
为std::string
时,return nullptr
从nullptr
构建一个字符串。 basic_string::_M_construct null not valid
基本上说
std::string(nullptr)
被调用。
它可能崩溃的另一个原因是get
函数返回一个指向局部变量的指针。函数返回时,局部变量被破坏。这导致未定义的行为。
修复:
bool get(T& result) {
std::lock_guard<std::mutex> lock(m);
if (v.empty())
return false;
result = v.front();
v.pop_front();
return true;
}
并调用它:
T removeMin() {
T result;
for(int i = 0; i < range; i++)
if(pqueue[i].get(result))
break;
return result;
}