std::shared_ptr<std::ostream> out_stream(const std::string &fname)
{
if (fname.length() > 0)
{
if ((fname.compare("stderr") == 0) || (fname.compare("cerr") == 0))
{
std::shared_ptr<std::ostream> p(&std::cerr, [](std::ostream*){});
return p;
}
if ((fname.compare("stdout") == 0) || (fname.compare("cout") == 0))
{
std::shared_ptr<std::ostream> p(&std::cout, [](std::ostream*){});
return p;
}
if ((fname.compare("null") == 0) || (fname.compare("/dev/null") == 0))
{
std::shared_ptr<std::ostream> p(new std::ofstream(0));//<<<<<<<<<<<<<<<<<<<<<
}
std::shared_ptr<std::ostream> p(new std::ofstream(fname));
io_utils_logger.log(utils::LogLevel::FILE, "opening a file ", fname, "\n");
return p;
}
else
{
std::shared_ptr<std::ostream> p(new std::ostream(std::cout.rdbuf()));
return p;
}
}
In the above source code, in the marked line, new std::ofstream(0) is showing the following error:
error: call of overloaded 'basic_ofstream(int)' is ambiguous
std::shared_ptr<std::ostream> p(new std::ofstream(0));
^
How can I fix it?
Related
I am getting a runtime error for this test case using stack
"bxj##tw", "bxj###tw"
Line 171: Char 16: runtime error: reference binding to misaligned address 0xbebebebebebec0ba for type 'int', which requires 4 byte alignment (stl_deque.h)
0xbebebebebebec0ba: note: pointer points here
<memory cannot be printed>
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_deque.h:180:16
class Solution {
public:
bool backspaceCompare(string s, string t) {
stack<int>st1;
stack<int>st2;
for(int i=0; i<s.size(); i++){
if(st1.empty() && s[i]!='#'){
st1.push(s[i]);
}
else{
if(!st1.empty() && s[i]=='#'){
st1.pop();
}
else if(s[i]=='#' && (st1.empty())){
continue;
}
else{
st1.push(s[i]);
}
}
}
for(int i=0; i < t.size(); i++){
if(st2.empty() && t[i]!='#'){
st2.push(t[i]);
}
else{
if(!st2.empty() && t[i]=='#'){
st2.pop();
}
else if(t[i]=='#' && st2.empty()){
continue;
}
else{
st2.push(t[i]);
}
}
}
if(st1.empty() && st2.empty()){
return "";
}
while(!st1.empty()){
if(st1.top()!= st2.top()){
return false;
}
else{
st1.pop();
st2.pop();
}
}
return true;
}
};
I wouldn't use a stack<char> since the natural representation is a string, and you're not using any functionality of the stack's ability to expand or shrink in the front (other than the end where you can just say return a == b). string has push_back and pop_back methods as well.
For small input (like the ones guaranteed for this challenge problem), I'd recommend constructing the two "editors" and comparing with ==:
class Solution {
public:
bool backspaceCompare(string s, string t) {
return backspace(s) == backspace(t);
}
private:
string backspace(const string &s) {
string editor = "";
string::const_iterator commandItr = s.cbegin();
while(commandItr != s.cend())
if(*commandItr == '#' && !editor.empty()) {
editor.pop_back();
++commandItr;
} else if(*commandItr != '#')
editor.push_back(*commandItr++);
else
++commandItr;
return editor;
}
};
However, they did challenge the coder to use O(1) memory. Here is an example of that:
class Solution {
public:
bool backspaceCompare(string s, string t) {
int left = s.size() - 1;
int right = t.size() - 1;
while(true) {
left = backspace(s, left);
right = backspace(t, right);
if (left == -1 && right == -1)
return true;
if (left == -1 && right != -1 || right == -1 && left != -1)
return false;
if(s[left--] != t[right--])
return false;
}
}
private:
// Returns first index from back that indexes to a non-deleted character
int backspace(string const &s, int startingIndex) {
if(startingIndex == -1)
return -1;
if(s[startingIndex] != '#')
return startingIndex;
unsigned backspaceCount = 0;
while(true) {
while(startingIndex != -1 && s[startingIndex] == '#') {
++backspaceCount;
--startingIndex;
}
while (startingIndex != -1 && backspaceCount && s[startingIndex] != '#') {
--startingIndex;
--backspaceCount;
}
if (startingIndex == -1)
return -1;
else if(s[startingIndex] != '#' && !backspaceCount)
return startingIndex;
}
}
};
Hello, i was solving this -> kata on CodeWars.
I am using a VusialStudio 2019 to write code. When i start this project in VS no erros is presented to me. The program even works correctly for the first test case. But when i am testing it on problem's page it gives me an error:
UndefinedBehaviorSanitizer:DEADLYSIGNAL
==1==ERROR: UndefinedBehaviorSanitizer: SEGV on unknown address 0x000000000000 (pc 0x000000429d24 bp 0x7ffc2f3f72b0 sp 0x7ffc2f3f7150 T1)
==1==The signal is caused by a READ memory access.
==1==Hint: address points to the zero page.
==1==WARNING: invalid path to external symbolizer!
==1==WARNING: Failed to use and restart external symbolizer!
#0 0x429d23 (/workspace/test+0x429d23)
#1 0x42ab1d (/workspace/test+0x42ab1d)
#2 0x429fa3 (/workspace/test+0x429fa3)
#3 0x42e2f2 (/workspace/test+0x42e2f2)
#4 0x42c9ce (/workspace/test+0x42c9ce)
#5 0x42c529 (/workspace/test+0x42c529)
#6 0x42c11b (/workspace/test+0x42c11b)
#7 0x431425 (/workspace/test+0x431425)
#8 0x42a08d (/workspace/test+0x42a08d)
#9 0x7f1b94116bf6 (/lib/x86_64-linux-gnu/libc.so.6+0x21bf6)
#10 0x4053e9 (/workspace/test+0x4053e9)
UndefinedBehaviorSanitizer can not provide additional info.
==1==ABORTING
For a while i was turning on and off parts of program to determen where the problem is. I nereved it down to this line
Program::Status_enum Program::ExecuteComand(Comand_Class* ComandToExe)
{
else if (ComandToExe->name == "div")
{
this->Registers[ComandToExe->args[0]] /= GetValue(ComandToExe->args[1]); // error here
}
}
Leter i found out that error was showing up even if i chage line to
this->Registers.begin()->second = 3; // same error
this->Registers["a"] = 2; // same error
It looks to me that any change of value causes it to throw an error. But reaading for example was ok
int a = Registers["a"];
std::cout << a; // will print a right value
So this basikly all i was able to find out by my self. Here is structer of my code.
Basikly my goal is to write a Asmbler intorpritator
// All Comands saved as this class
class Comand_Class
{
public:
std::string name; // for example mov, div, etc.
std::vector<std::string> args; // data for the comand
Comand_Class(std::string Name, std::string arg1 = "", std::string arg2 = "")
{
//..
}
Comand_Class(std::string Name, std::vector<std::string> Args)
{
//..
}
};
// I use this class to store functions cod as a small program itself
class Function_Class
{
public:
std::vector<Comand_Class*> FunctionProgram;
};
// the main class
class Program
{
std::string MSG = "-1"; // for outout
std::unordered_map <std::string, int> Registers; // map in which the problem exsist
std::vector<Comand_Class*> ProgramLines; // Starting code
std::map<std::string,Function_Class*> CallList; // Name of Function and Her code to exe
// .exe is giving me back the status, after executing a Comand_Class line, this how i know what to do next.
enum Status_enum
{
END = 0,
CALL = 1,
JUMP = 2,
RET = 3,
CONTINUE = 10,
ERROR = -1,
};
public:
std::string Start()
{
exe(this -> ProgramLines );
return MSG;
}
int GetValue(std::string arg)
{
if ('a' <= arg[0] && arg[0] <= 'z')
{
//register
return this->Registers[arg];
}
else
{
int a = std::stoi(arg);
return a;
}
}
// not related to the problem,
void preprocesing(std::string program);
Status_enum ExecuteComand(Comand_Class* ComandToExe);
void exe(std::vector<Comand_Class*> ProgramLinesToExe);
~Program()
{
for (unsigned long i = 0; i < ProgramLines.size(); i++)
{
Comand_Class* del = ProgramLines.at(i);
delete del;
}
for (auto it = CallList.begin(); it != CallList.end(); it++)
{
for (unsigned long i = 0; i < it->second->FunctionProgram.size(); i++)
{
Comand_Class* del = it->second->FunctionProgram.at(i);
delete del;
}
}
// add CallList to clear
}
};
// this function is recurseve, Can this be a reson why it brakes?
void Program::exe(std::vector<Comand_Class*> ProgramLinesToExe)
{
Status_enum Status;
unsigned long int SubPC = 0; // Comand to exe
while (SubPC < ProgramLinesToExe.size())
{
Status = ExecuteComand(ProgramLinesToExe[SubPC]);
if (Status != CONTINUE)
{
if(Status == JUMP)
{
exe(CallList[ProgramLinesToExe[SubPC]->args[0]]->FunctionProgram);
}
else if (Status == CALL)
{
auto test = CallList[ProgramLinesToExe[SubPC]->args[0]]->FunctionProgram;
exe(CallList[ProgramLinesToExe[SubPC]->args[0]]->FunctionProgram);
}
else if (Status == RET)
{
return;
}
else if (Status == END)
{
break;
}
else if (Status == ERROR)
{
std::cout << "Unknown comand! " << ProgramLinesToExe[SubPC]->name;
}
}
SubPC++;
}
}
// Untill this function called second time (recursively) all works good
Program::Status_enum Program::ExecuteComand(Comand_Class* ComandToExe)
{
if (ComandToExe->name == "mov")
{
this->Registers[ComandToExe->args[0]] = GetValue(ComandToExe->args[1]);
}
else if (ComandToExe->name == "inc")
{
this->Registers[ComandToExe->args[0]]++;
}
else if (ComandToExe->name == "dec")
{
this->Registers[ComandToExe->args[0]]--;
}
else if (ComandToExe->name == "add")
{
this->Registers[ComandToExe->args[0]] += GetValue(ComandToExe->args[1]);
}
else if (ComandToExe->name == "sub")
{
this->Registers[ComandToExe->args[0]] -= GetValue(ComandToExe->args[1]);
}
else if (ComandToExe->name == "mil")
{
this->Registers[ComandToExe->args[0]] *= GetValue(ComandToExe->args[1]);
}
else if (ComandToExe->name == "div")
{
//this->Registers[ComandToExe->args[0]] /= GetValue(ComandToExe->args[1]); error
}
else if (ComandToExe->name == "cmp")
{
int x = GetValue(ComandToExe->args[0]);
int y = GetValue(ComandToExe->args[1]);
this->CompareFlugs.Equal = (x == y);
this->CompareFlugs.Less = (x < y);
}
else if (ComandToExe->name == "jne") // if the values of the previous cmp command were not equal.
{
if (this->CompareFlugs.Equal == false)
{
return JUMP;
}
}
else if (ComandToExe->name == "je") // if the values of the previous cmp command were equal.
{
if (this->CompareFlugs.Equal == true)
{
return JUMP;
}
}
else if (ComandToExe->name == "jge") // if x was greater or equal than y in the previous cmp command.
{
if (this->CompareFlugs.Less == false)
{
return JUMP;
}
}
else if (ComandToExe->name == "jg") // f x was greater than y in the previous cmp command.
{
if ((this->CompareFlugs.Less == false) && (this->CompareFlugs.Equal == false))
{
return JUMP;
}
}
else if (ComandToExe->name == "jle") // if x was less or equal than y in the previous cmp command.
{
if ((this->CompareFlugs.Less == true) || (this->CompareFlugs.Equal == true))
{
return JUMP;
}
}
else if (ComandToExe->name == "jl") // if x was less than y in the previous cmp command.
{
if (this->CompareFlugs.Less == true)
{
return JUMP;
}
}
else if (ComandToExe->name == "call")
{
return CALL;
}
else if (ComandToExe->name == "ret")
{
return RET;
}
else if (ComandToExe->name == "end")
{
return END;
}
else if (ComandToExe->name == "msg")
{
MSG = "";
for (unsigned long int i = 0; i < ComandToExe->args.size(); i++)
{
if (ComandToExe->args[i][0] == '\'')
{
MSG += ComandToExe->args[i].substr(1);
}
else
{
MSG += std::to_string(GetValue(ComandToExe->args[i]));
}
}
}
else
{
return ERROR;
}
return CONTINUE;
}
That's all. Also i am new to stackoverflow, so if i did somting very bad, do not judge strictly.
And Here all the code, becase i cut parts i think was usless:
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <map>
#include <unordered_map>
#include <regex>
class Comand_Class
{
public:
std::string name;
std::vector<std::string> args;
Comand_Class(std::string Name, std::string arg1 = "", std::string arg2 = "")
{
name = Name;
args.push_back(arg1);
if (!arg2.empty())
{
args.push_back(arg2);
}
}
Comand_Class(std::string Name, std::vector<std::string> Args)
{
name = Name;
args = Args;
}
};
class Function_Class
{
public:
//Comand_Class* ReturnControlTo = NULL;
std::vector<Comand_Class*> FunctionProgram;
};
class Program
{
//int PC = 0;
std::string MSG = "-1";
std::unordered_map <std::string, int> Registers;
std::vector<Comand_Class*> ProgramLines;
std::map<std::string,Function_Class*> CallList;
class CompareFlugs_Class
{
public:
bool Less = false;
bool Equal = false;
}CompareFlugs;
enum Status_enum
{
END = 0,
CALL = 1,
JUMP = 2,
RET = 3,
CONTINUE = 10,
ERROR = -1,
};
const std::string AllowedCommands = "mov inc dev add sub mul div cmp";
public:
std::string Start()
{
exe(this -> ProgramLines );
return MSG;
}
int GetValue(std::string arg)
{
if ('a' <= arg[0] && arg[0] <= 'z')
{
//register
return this->Registers[arg];
}
else
{
int a = std::stoi(arg);
return a;
}
}
void preprocesing(std::string program);
Status_enum ExecuteComand(Comand_Class* ComandToExe);
void exe(std::vector<Comand_Class*> ProgramLinesToExe);
~Program()
{
for (unsigned long i = 0; i < ProgramLines.size(); i++)
{
Comand_Class* del = ProgramLines.at(i);
delete del;
}
for (auto it = CallList.begin(); it != CallList.end(); it++)
{
for (unsigned long i = 0; i < it->second->FunctionProgram.size(); i++)
{
Comand_Class* del = it->second->FunctionProgram.at(i);
delete del;
}
}
// add CallList to clear
}
};
void Program::preprocesing(std::string program)
{
std::string read;
Comand_Class*NewProgramLine;
std::istringstream iss(program);
std::smatch matches;
std::regex Comand(";(.*)|call\\s(.*)|(end|ret)|msg(.*)[;]?|(\\w+):|(j\\w{1,2})\\s+(\\w+)|(\\w+)\\s+(\\w),?\\s?(\\d+|\\w)?");
bool WtireToFunction = false;
std::string ActiveLabel;
Function_Class* NewFunction = nullptr;// = new Function_Class;
while (!iss.eof())
{
std::getline(iss, read);
std::regex_search(read, matches, Comand);
/*
if (matches.size() != 0)
std::cout << "Comand is " << matches[0] << "\n";
*/
// parcing
std::string Coment = matches[1];
std::string CallLabel = matches[2];
std::string End = matches[3];
std::string Message = matches[4]; // may contain a comment in the end
std::string Label = matches[5];
std::string JumpComand = matches[6];
std::string JumpLabel = matches[7];
std::string ComandName = matches[8];
std::string arg1 = matches[9];
std::string arg2 = matches[10];
if ((!ComandName.empty()) && (AllowedCommands.find(ComandName) != std::string::npos))
{
//std::cout << "Comand is " << matches[0] << "\n";
std::cout << "Comand is " << ComandName << " " << arg1 << " " << arg2 << "\n";
NewProgramLine = new Comand_Class (ComandName,arg1,arg2);
//NewProgramLine->name = ComandName;
//NewProgramLine->args.push_back(arg1);
if (WtireToFunction == false)
{
this->ProgramLines.push_back(NewProgramLine);
}
else
{
NewFunction->FunctionProgram.push_back(NewProgramLine);
}
}
else if (!JumpComand.empty()) // && (AllowedJumpComands.find(JumpComand) != std::string::npos))
{
std::cout << "Comand is " << JumpComand << " " << JumpLabel << "\n";
NewProgramLine = new Comand_Class(JumpComand, JumpLabel);
}
else if (!CallLabel.empty()) // on call
{
NewProgramLine = new Comand_Class("call", CallLabel);
this->ProgramLines.push_back(NewProgramLine); // add Call to the ProgramLines
}
else if (!Label.empty()) // Generate New SubProgram
{
WtireToFunction = true;
ActiveLabel = Label;
NewFunction = new Function_Class;
this->CallList[ActiveLabel] = NewFunction;
}
else if (!Message.empty())
{
std::regex MessageParcing("('.*)'|,\\s(\\w)");
std::smatch matches;
std::sregex_iterator it(Message.begin(), Message.end(), MessageParcing), end;
std::vector<std::string> args;
while (it!= end)
{
matches = *it;
if (!matches[1].str().empty())
{
args.push_back(matches[1].str());
}
else if (!matches[2].str().empty())
{
args.push_back(matches[2].str());
}
else
{
std::cout << "Error: cannot format msg\n";
}
it++;
}
NewProgramLine = new Comand_Class("msg",args);
this->ProgramLines.push_back(NewProgramLine);
}
else if (!End.empty())
{
if (End == "end")
{
NewProgramLine = new Comand_Class("end");
this->ProgramLines.push_back(NewProgramLine); // add Call to the ProgramLines
}
if (End == "ret")
{
if (NewFunction == nullptr)
std::cout << "No Call Detected, but ret is found\n";
else
{
NewProgramLine = new Comand_Class("ret");
NewFunction->FunctionProgram.push_back(NewProgramLine);
}
}
}
}
}
Program::Status_enum Program::ExecuteComand(Comand_Class* ComandToExe)
{
if (ComandToExe->name == "mov")
{
this->Registers[ComandToExe->args[0]] = GetValue(ComandToExe->args[1]);
}
else if (ComandToExe->name == "inc")
{
this->Registers[ComandToExe->args[0]]++;
}
else if (ComandToExe->name == "dec")
{
this->Registers[ComandToExe->args[0]]--;
}
else if (ComandToExe->name == "add")
{
this->Registers[ComandToExe->args[0]] += GetValue(ComandToExe->args[1]);
}
else if (ComandToExe->name == "sub")
{
this->Registers[ComandToExe->args[0]] -= GetValue(ComandToExe->args[1]);
}
else if (ComandToExe->name == "mil")
{
this->Registers[ComandToExe->args[0]] *= GetValue(ComandToExe->args[1]);
}
else if (ComandToExe->name == "div")
{
int a = GetValue(ComandToExe->args[1]);
auto t = ComandToExe->args[0];
int b = 6 / 2;
this->MSG = "Hi";
this->Registers[t] = b;
this->Registers.begin()->second = 3;
//this->Registers[ComandToExe->args[0]] /= GetValue(ComandToExe->args[1]);
}
else if (ComandToExe->name == "cmp")
{
int x = GetValue(ComandToExe->args[0]);
int y = GetValue(ComandToExe->args[1]);
this->CompareFlugs.Equal = (x == y);
this->CompareFlugs.Less = (x < y);
}
else if (ComandToExe->name == "jne") // if the values of the previous cmp command were not equal.
{
if (this->CompareFlugs.Equal == false)
{
return JUMP;
}
}
else if (ComandToExe->name == "je") // if the values of the previous cmp command were equal.
{
if (this->CompareFlugs.Equal == true)
{
return JUMP;
}
}
else if (ComandToExe->name == "jge") // if x was greater or equal than y in the previous cmp command.
{
if (this->CompareFlugs.Less == false)
{
return JUMP;
}
}
else if (ComandToExe->name == "jg") // f x was greater than y in the previous cmp command.
{
if ((this->CompareFlugs.Less == false) && (this->CompareFlugs.Equal == false))
{
return JUMP;
}
}
else if (ComandToExe->name == "jle") // if x was less or equal than y in the previous cmp command.
{
if ((this->CompareFlugs.Less == true) || (this->CompareFlugs.Equal == true))
{
return JUMP;
}
}
else if (ComandToExe->name == "jl") // if x was less than y in the previous cmp command.
{
if (this->CompareFlugs.Less == true)
{
return JUMP;
}
}
else if (ComandToExe->name == "call")
{
// написать адресс для возврата в структуру с функциями
return CALL;
}
else if (ComandToExe->name == "ret")
{
return RET;
}
else if (ComandToExe->name == "end")
{
return END;
}
else if (ComandToExe->name == "msg")
{
MSG = "";
for (unsigned long int i = 0; i < ComandToExe->args.size(); i++)
{
if (ComandToExe->args[i][0] == '\'')
{
MSG += ComandToExe->args[i].substr(1);
}
else
{
MSG += std::to_string(GetValue(ComandToExe->args[i]));
}
}
}
else
{
return ERROR;
}
return CONTINUE;
}
void Program::exe(std::vector<Comand_Class*> ProgramLinesToExe)
{
Status_enum Status;
unsigned long int SubPC = 0;
while (SubPC < ProgramLinesToExe.size())
{
Status = ExecuteComand(ProgramLinesToExe[SubPC]);
if (Status != CONTINUE)
{
if(Status == JUMP)
{
exe(CallList[ProgramLinesToExe[SubPC]->args[0]]->FunctionProgram);
}
else if (Status == CALL)
{
auto test = CallList[ProgramLinesToExe[SubPC]->args[0]]->FunctionProgram;
exe(CallList[ProgramLinesToExe[SubPC]->args[0]]->FunctionProgram);
}
else if (Status == RET)
{
return;
}
else if (Status == END)
{
break;
}
else if (Status == ERROR)
{
std::cout << "Unknown comand! " << ProgramLinesToExe[SubPC]->name;
}
}
SubPC++;
}
}
std::string assembler_interpreter(std::string program)
{
Program Main;
Main.preprocesing(program);
return Main.Start();
}
I use Google’s dense_hash_map as a cache of some data. When I use the find function to find a key, I find that it doesn’t exist, but when traversing dense_hash_map, I can see that the key exists. Is it wrong where I used it? By the way, I have rewritten the EqualKey class required by dense_hash_map.
This is my test code:
class StringVal {
public:
StringVal(string &str) {
len = str.length();
ptr = new uint8_t[len];
memcpy(ptr, str.c_str(), len);
}
StringVal(uint8_t* ptr = NULL, int len = 0) : len(len), ptr(ptr) {
if(ptr == NULL) {
is_null = NULL;
}
}
StringVal(const char* ptr) : len(strlen(ptr)),ptr(const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(ptr))) {
if(ptr == NULL) {
is_null = NULL;
}
}
~StringVal() {
delete[] ptr;
}
uint8_t* ptr;
int len;
bool is_null;
static StringVal null() {
StringVal sv;
sv.is_null = true;
return sv;
}
bool operator==(const StringVal& other) const {
if (is_null != other.is_null) return false;
if (is_null) return true;
if (len != other.len) return false;
return ptr == other.ptr || memcmp(ptr, other.ptr, len) == 0;
}
bool operator!=(const StringVal& other) const { return !(*this == other); }
};
struct NewStringValCmp {
bool operator()(const StringVal* s1, const StringVal* s2) const {
if (s1 == NULL && s2 == NULL) return 1;
if (s1 == NULL || s2 == NULL) return 0;
if (s1->is_null != s2->is_null) return false;
if (s1->is_null) return true;
if (s1->len != s2->len) return false;
return memcmp(s1->ptr, s2->ptr, s1->len) == 0;
}
};
typedef dense_hash_map<StringVal*, StringVal*, std::hash<StringVal*>, NewStringValCmp> new_dict_map_string_t;
vector<string> data = {
"test1","1",
"test2","2",
"test3","3",
"test4","4",
"test5","5",
"test6","6",
"test7","7",
"test8","8",
"test9","9",
"test10","10"
};
int main() {
new_dict_map_string_t* cm = new new_dict_map_string_t();
cm->set_empty_key(NULL);
for (int i = 0; (i + 1) < data.size(); i+=2) {
StringVal *key = new StringVal(data[i]);
StringVal *value = new StringVal(data[i+1]);
(*cm)[key] = value;
}
string input = "";
while (1) {
cin >> input;
if (input == "q") {
break;
}
StringVal *target = new StringVal(input);
for (auto itor: *cm) {
if (*(itor.first) == *target) {
cout << "find target" << endl;
}
}
auto itor = cm->find(target);
if (itor == cm->end()) {
cout << "cm->find nothing" << endl;
} else {
cout << itor->second->ptr << endl;
}
delete target;
input = "";
}
for (auto iter : *cm) {
delete iter.first;
delete iter.second;
}
delete cm;
return 0;
}
In the followring code,
class MonitorResult {
public:
void putDir(std::string && dir) { }
};
void listDir(boost::filesystem::path && dir, MonitorResult & result) {
for(boost::filesystem::directory_iterator it(dir);
it != boost::filesystem::directory_iterator(); ++it) {
if(boost::filesystem::is_symlink( it->path()) ) {
continue;
}
else if(boost::filesystem::is_directory(it->path())) {
result.putDir(it->path().string() ); // Error here
}
}
}
error: no matching function for call to MonitorResult::putDir(const string&)
candidate is void MonitorResult::putDir(std::string&&)
I am not getting std::string, but just string. How can type error be resolved? Thanks.
Here's the code :
The place where it crashed is marked with a comment(//////crash).
I don't know what results in the problem.
After I print the size of data got from file,It shows '1' means that the array should only contains 1 element. So it seems that there's no 'bad_allocate error' ...
Could you guys help me ? I would appreciate your kindly help very much. :)
#include<stdio.h>
#include<iostream>
#include<string>
#include<map>
#include<vector>
#include<algorithm>
#include<string.h>
#include<type_traits>
using namespace std;
bool read_int(int& val,FILE*& fp)
{
if(fp == nullptr)
return false;
fread(&val,sizeof(int),1,fp);
return true;
}
bool write_int(int val,FILE*& fp)
{
if(fp == nullptr)
{
return false;
}
fwrite(&val,sizeof(int),1,fp);
return true;
}
struct SANOBJ
{
char path[128];
char nickname[40];
SANOBJ(const char* _p = nullptr,const char* _n = nullptr)
{
if(_p == nullptr || _n == nullptr)
*this = {};
int m = strlen(_p),n = strlen(_n);
if(m < 128) strcpy(path,_p);
if(n < 40) strcpy(nickname,_n);
}
~SANOBJ(){}
SANOBJ(const SANOBJ& other)
{
memcpy(path,other.path,sizeof(char) * 128);
memcpy(nickname,other.nickname,sizeof(char) * 40);
}
bool operator < (const SANOBJ& other) const
{
return string(path) < string(other.path);
}
bool operator == (const SANOBJ& other) const
{
return (strcmp(other.path,path) == 0);
}
};
template <typename source_type> //the 'source_type' type need to have the member 'int m_index'
class FrameQueue
{
public:
FrameQueue() //fill the 1st frame automatically
{
source_type new_node;
new_node.m_index = 0;
m_data.push_back(new_node);
}
FrameQueue(const FrameQueue& other)
{
m_data = other.m_data;
}
bool AddFrame(const source_type& other) // keeps an ascending order
{
int index = _binary_search(other);
if(index != -1)
{
return false;
}
m_data.insert(std::upper_bound(m_data.begin(),m_data.end(),other,
[](const source_type& a,const source_type& b)->bool const{return a.m_index < b.m_index;}
),other);
return true;
}
bool DeleteFrameByElemIndex(int elemIndex) //delete frame according to the index of frame in the queue
{
if(elemIndex < 0)
return false;
if(elemIndex >= m_data.size())
return false;
typename std::vector<source_type>::iterator it ;
it = m_data.begin() + elemIndex;
it = m_data.erase(it);
return true;
}
bool DeleteFrameByFrameIndex(int frameIndex)
{
source_type node = {};
node.m_index = frameIndex;
int index = _binary_search(node);
if(index == -1)
{
return false;
}
typename std::vector<source_type>::iterator it;
it = m_data.begin() + index;
it = m_data.erase(it);
return true;
}
bool Clear() // There would always be a single frame
{
source_type new_node = {};
new_node.m_index = 0;
m_data.clear();
m_data.push_back(new_node);
return true;
}
bool WriteFile(FILE*& fp)
{
if(fp == nullptr)
return false;
bool result = write_int(m_data.size(),fp);
if(result == false)
return false;
fwrite(&(m_data[0]),sizeof(source_type),m_data.size(),fp);
return true;
}
bool ReadFile(FILE*& fp)
{
if(fp == nullptr)
return false;
int data_size;
bool result = read_int(data_size,fp);
if(result == false)
return false;
if(data_size > 0)
{
m_data.resize(data_size);
fread(&(m_data[0]),sizeof(source_type),data_size,fp);
}
return true;
}
private:
int _binary_search(source_type target)
{
int l = 0,r = (int)m_data.size() - 1,mid;
while(l<=r)
{
mid = (l + r) / 2;
if(m_data[l].m_index == target.m_index)
{
return l;
}
if(m_data[r].m_index == target.m_index)
{
return r;
}
if(m_data[mid].m_index == target.m_index)
{
return mid;
}
if(m_data[mid].m_index > target.m_index)
{
r = mid - 1;
}
else
{
l = mid + 1;
}
}
return -1;
}
public:
vector<source_type> m_data;
};
template<typename source_type>
class UniqueSource
{
public:
UniqueSource(){}
~UniqueSource(){}
bool Add(const source_type& other)//return false when insert failed,otherwise return true
{
if(m_map_source_to_index.find(other) == m_map_source_to_index.end())
{
int map_size = m_map_source_to_index.size();
m_data.push_back(other);
m_map_source_to_index.insert(pair<source_type,int>(other,map_size));
m_result.push_back(map_size);
return true;
}
else
{
m_result.push_back(m_map_source_to_index[other]);
return true;
}
return false;
}
bool Delete(int elemIndex) // delete the elem by elem Index,If succeed ,return true,otherwise return false
{
if(elemIndex < 0)
return false;
if(elemIndex >= m_data.size())
return false;
typename std::map<source_type,int>::iterator mit;
typename std::vector<source_type>::iterator vit;
for(mit = m_map_source_to_index.begin();mit!=m_map_source_to_index.end();++mit)
{
m_map_source_to_index.erase(mit);
}
vit = m_data.begin() + elemIndex;
m_data.erase(vit);
return true;
}
bool Clear()
{
m_map_source_to_index.clear();
m_data.clear();
m_result.clear();
return true;
}
bool WriteFile(FILE*& fp)
{
if(fp == nullptr)
return false;
bool result = write_int(m_data.size(),fp);
if(result == false)
return false;
if(m_data.size() > 0)
fwrite(&(m_data[0]),sizeof(source_type),m_data.size(),fp);
result = write_int(m_result.size(),fp);
if(result == false)
return false;
if(m_result.size() > 0)
fwrite(&(m_result[0]),sizeof(int),m_result.size(),fp);
return true;
}
bool ReadFile(FILE*& fp)
{
if(fp == nullptr)
return false;
Clear();
int data_size;
read_int(data_size,fp);
if(data_size > 0)
{
printf("[%d]",data_size);
m_data.resize(data_size); /////////////////Crash!!!!!!!!!!!!
printf("Resize Ok\r\n");
fread(&(m_data[0]),sizeof(source_type),data_size,fp);
}
read_int(data_size,fp);
printf("[%d]",data_size);
if(data_size > 0)
{
m_result.resize(data_size);
fread(&(m_result[0]),sizeof(int),data_size,fp);
}
return true;
}
//private:
map<source_type,int> m_map_source_to_index;
vector<source_type> m_data;
vector<int> m_result; //the index I want
};
int main()
{
UniqueSource<SANOBJ> m;
SANOBJ t = {"123","456"};
m.Add(t);
printf("Added\r\n");
FILE* fp = nullptr;
fp = fopen("test.b","wb");
if(fp == nullptr)
{
printf("Failed...\r\n");
}
bool ret = false;
ret = m.WriteFile(fp);
if(ret)
{
printf("Writed!\r\n");
fclose(fp);
}
fp = fopen("test.b","rb");
if(fp == nullptr)
{
printf("Failed...\r\n");
}
ret = m.ReadFile(fp);
fclose(fp);
printf("Readed\r\n");
for(int i=0;i<m.m_data.size();i++)
printf("%s %s\r\n",m.m_data[i].path,m.m_data[i].nickname);
return 0;
}
*this = {} default-constructs a new SANOBJ instance and then assigns it to *this. This would normally be OK, but here you are calling it from the SANOBJ default constructor (making the logic being something like "to default-construct a SANOBJ, default-construct a SANOBJ and then assign its value to myself"), leading to infinite recursion and eventually a stack overflow.
Sidenote: The copy constructor is not needed.
Yes. The problem is is with *this = {}
If I were you, I'd rewrite SANOBJ constructor like this (this is a rough code and you may need to slightly modify it if you wish)
SANOBJ(const char* _p = nullptr,const char* _n = nullptr)
{
if (( _p != nullptr ) && ((strlen(_p) < 128)))
strcpy(path,_p);
if (( _n != nullptr ) && ((strlen(_n) < 40)))
strcpy(nickname,_n);
}
It'll resolve the problem.
Naturally, I don't play with *this (not this).
If you want to be sure that the member variables are empty (char path[128] and char nickname[40])
set at the beginning of the constructor something like:
path[0] = '\0';
nickname[0] = '\0';
Or use something like on constructor:
SANOBJ(const char* _p = nullptr,const char* _n = nullptr)
: path(), nickname()
{
}
But don't use *this= {}