I am writing HTTP client in C++. When I was testing my program he crashed with this error:
*** Error in `./isabot': free(): invalid pointer: 0x00007ffe7f8d2600 ***
======= Backtrace: =========
/lib64/libc.so.6(+0x81299)[0x7fef1fd86299]
./isabot[0x408eca]
./isabot[0x409afe]
/lib64/libc.so.6(__libc_start_main+0xf5)[0x7fef1fd27555]
./isabot[0x402d59]
======= Memory map: ========
.
.
.
I reran my program with valgrind -v and I got this error:
==20879== Invalid free() / delete / delete[] / realloc()
==20879== at 0x4C2B18A: operator delete(void*) (vg_replace_malloc.c:576)
==20879== by 0x408EC9: sendRequest(ssl_st*, int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (in /homes/eva/xm/xmimoc01/ISA/isabot)
==20879== by 0x409AFD: main (in /homes/eva/xm/xmimoc01/ISA/isabot)
==20879== Address 0x1ffeffee00 is on thread 1's stack
==20879== in frame #1, created by sendRequest(ssl_st*, int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (???:)
==20879==
When I started my program without valgrind, the program crashed on this. But, when I started my program with valgrind, it wrote to me an error and the program continued successfully without repetition this error.
My function sendRequest() looks like:
string sendRequest(SSL *ssl, int requestType, const string &botToken, const string &guildId, const string &channelId, const string &lastMessageId, const string &content)
{
const char *request;
string strRequest;
stringstream response;
string isChunked;
char buffer[BUFFER];
if (requestType == GET_CLIENT_ID) {
strRequest = createIDRequest(botToken);
}
else if (requestType == GET_GUILDS) {
strRequest = createGuildsRequest(botToken);
}
else if (requestType == GET_CHANNELS) {
strRequest = createChannelRequest(botToken, guildId);
}
else if (requestType == GET_MESSAGES) {
strRequest = createMessagesRequest(botToken, channelId);
}
else if (requestType == GET_ACTUAL_MESSAGES) {
strRequest = createActualMessagesRequest(botToken, channelId, lastMessageId);
}
else if(requestType == POST_SEND_MESSAGE) {
strRequest = createSendMessageRequest(botToken, channelId, content);
}
request = strRequest.c_str();
SSL_write(ssl, request, strlen(request));
while(true) {
memset(buffer, 0, sizeof(buffer));
int n = SSL_read(ssl, buffer, BUFFER);
if(n >= 0) {
buffer[n] = '\0';
}
if (n <= 5) {
break;
};
response << buffer;
if (isResponseChunked(response.str()) != true) {
break;
}
}
return response.str();
}
and I called it from main.cpp in part of code where it crashed like this:
string sendedMessage = sendRequest(conn.ssl, POST_SEND_MESSAGE, botToken, "", channelId, "", content);
buffer[n] = '\0'; will write past the end of buffer when n == BUFFER. This overwrites some part of the stack, likely snother local variable. If it is one of the string variables, the internal state is corrupted which could result in this error.
The simple fix is to allocate one additional character in buffer.
char buffer[BUFFER+1];
Alternatively, you could read one less byte in the call to SSL_read.
Related
This question already has answers here:
How to get the real and total length of char * (char array)?
(15 answers)
Closed 4 years ago.
How do I get the length of const char* arrays indexes?
The vector:
std::vector<const char*> _infoBarText;
The const char* []:
const char* text[4] = {"Current T:", "Target T:", "Time elapsed:", "Time remaining:"};
Assigning the char array to the vector:
_infoBarText.assign(text, text+4);
How can I get the length of the individual strings, like "current T", from the vector?
Raw C strings (bare char*-s) are not a perfect fit for modern C++ code.
If you change it to std::vector<std::string_view> you get your problem solved without (virtually) any overhead (given you are initializing it with literals) and as a bonus you will potentially make it safer and more usable.
See the cppreference article for details.
Example (GodBolt):
#include <string_view>
#include <vector>
#include <iostream>
int main() {
using namespace std::literals;
std::vector<std::string_view> strs = { "hello"sv, "there"sv };
for (auto&& str: strs)
std::cout << str << str.size();
return 0;
}
GodBolt Code Insight Output (note the std::operator""sv("hello", 5ul)):
#include <string_view>
#include <vector>
#include <iostream>
int main()
{
using namespace std::literals;
std::vector<std::string_view> strs = std::vector<std::basic_string_view<char, std::char_traits<char> >, std::allocator<std::basic_string_view<char, std::char_traits<char> > > >{std::initializer_list<std::basic_string_view<char, std::char_traits<char> > >{std::operator""sv("hello", 5ul), std::operator""sv("there", 5ul)}, std::allocator<std::basic_string_view<char, std::char_traits<char> > >()};
{
std::vector<std::basic_string_view<char, std::char_traits<char> >, std::allocator<std::basic_string_view<char, std::char_traits<char> > > > & __range = strs;
__gnu_cxx::__normal_iterator<std::basic_string_view<char, std::char_traits<char> > *, std::vector<std::basic_string_view<char, std::char_traits<char> >, std::allocator<std::basic_string_view<char, std::char_traits<char> > > > > __begin = __range.begin();
__gnu_cxx::__normal_iterator<std::basic_string_view<char, std::char_traits<char> > *, std::vector<std::basic_string_view<char, std::char_traits<char> >, std::allocator<std::basic_string_view<char, std::char_traits<char> > > > > __end = __range.end();
for( ; __gnu_cxx::operator!=(__begin, __end); __begin.operator++() )
{
std::basic_string_view<char, std::char_traits<char> > & str = __begin.operator*();
std::operator<<(std::cout, std::basic_string_view<char, std::char_traits<char> >(str)).operator<<(str.size());
}
}
return 0;
}
The long way:
#include <vector>
#include <cstring> // for strlen
std::vector<const char*> _infoBarText;
char const *str = _infoBarText[0]; // or any other valid index
auto len = std::strlen(str);
Short:
auto len = std::strlen(_infoBarText[0]);
After compiling my hash_multimap I get this large one paragraph error for my
In member function ‘size_t __gnu_cxx::hashtable<
I have never seen this huge error and I'm actually not sure what to do to fix this error due to it's abnormal size.
Any suggestions why line:
p = map1.equal_range(searchKey);
is causing this abnormaly long error? FYI- I cut the whole error and removed the middle part because once I pasted it here it was like a page long O.o
ERROR
/usr/include/c++/4.3/backward/hashtable.h: In member function ‘size_t
__gnu_cxx::hashtable<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey,
_Alloc>::_M_bkt_num_key(const _Key&, size_t) const [with _Val =
std::pair<const std::basic_string<char, std::char_traits<char>,
std::allocator<char> >, Map2*>, _Key = std::basic_string<char
...
std::char_traits<char>, std::allocator<char> > >, _Alloc =
std::allocator<Map2*>]’
hash_map2.cpp:55: instantiated from here
/usr/include/c++/4.3/backward/hashtable.h:595: error: no match for call to
‘(const __gnu_cxx::hash<std::basic_string<char, std::char_traits<char>,
std::allocator<char> > >) (const std::basic_string<char,
std::char_traits<char>, std::allocator<char> >&)’
Map.h file
#ifndef MAP2_H
#define MAP2_H
#include <iostream>
#include <string>
using namespace std;
class Map2 {
public:
Map2(string data1, string data2, string data3, string data4, string data5);
string pop, keyword, user, desc, id;
string get_pop() {return pop;}
string get_key() {return keyword;}
string get_user() {return user;}
string get_desc() {return desc;}
string get_id() {return id;}
void call_Values(int i);
};
Map2:: Map2(string data1, string data2, string data3, string data4, string data5) {
pop = data1;
keyword = data2;
user = data3;
desc = data4;
id = data5;
}
void Map2:: call_Values(int i) {
get_pop();
get_key();
get_user();
get_desc();
get_id();
}
#endif
hash_map2.cpp
#include <fstream>
#include <iostream>
#include "Map2.h"
#include <ext/hash_map>
#include <string>
#include <sstream>
using namespace std;
using __gnu_cxx::hash_multimap;
int nav() {
cout <<"Select from the following options : " << endl <<endl;
cout <<"Search Tweets based on Keyword (Type 1) " <<endl;
cout <<"End Program (Type 2)"<<endl<<endl;
int key =0;
cin >> key;
return key;
}
int main() {
int option = nav();
if (option == 1) {
ifstream readFile("project4.csv");
string tempPop, tempID, tempKey, tempUser, tempDesc;
string tempRead;
hash_multimap<string, Map2 *>map1;
while (readFile != NULL){
// sends to a temp variable
readFile >> tempRead;
for (int i =0; i<400; i++){
//create new object each time
Map2 *mapNode = new Map2(tempPop,tempID,tempKey,tempUser,tempDesc);
//insert each time new object is made
map1.insert(pair<string, Map2 *> (tempKey, mapNode));
} //end for
} //end while
//Navigation through multimap
//first pointer is for first one and second to last hash table value
pair<hash_multimap<string, Map2 *> :: const_iterator,
hash_multimap<string, Map2 *> :: const_iterator> p;
string searchKey = "";
cout << "Please enter the keyword value exactly so we can search the"<<
"available tweets: " <<endl;
cin >> searchKey;
p = map1.equal_range(searchKey);
}
else
return 0;
}
Issue is the fact of calling string to search. Need to convert the string to int before calling the value inside the equal_range function.
I'm trying to compile some c++ code on os x using g++ in the terminal. However, I keep getting an error and I'm unsure of what it means. I have 3 files, main.cpp; comp_fns.cpp and comp_fns.h. Window and Gene are two different classes. Here is the error:
g++ -Wall main.cpp comp_fns.cpp
duplicate symbol Window::setValues(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >)in:
/var/folders/jf/3y93rsfd1n55q2qd75y0w0r00000gn/T//cc51aFZg.o
/var/folders/jf/3y93rsfd1n55q2qd75y0w0r00000gn/T//cc2KNfcB.o
duplicate symbol Gene::setValues(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >)in:
/var/folders/jf/3y93rsfd1n55q2qd75y0w0r00000gn/T//cc51aFZg.o
/var/folders/jf/3y93rsfd1n55q2qd75y0w0r00000gn/T//cc2KNfcB.o
ld: 2 duplicate symbols for architecture x86_64
collect2: ld returned 1 exit status
Any help would be much appreciated, and I can post the code if needed.
EDIT: I did not #include one cpp file into another. Here is my header file, where I think the issue may be at. This is my first cpp program so there might be some obvious mistakes. I originally wrote it in C and am changing it over to c++ so I can learn how to do both.
#ifndef __Compare_Data_C____comp_fns__
#define __Compare_Data_C____comp_fns__
#include <iostream>
#include <cstdlib>
#include <string>
#include <sstream>
using namespace std;
class Window {
public:
int start, stop, length;
double average;
string strandID, locations;
void setValues(string locs, string strand, string length, string avg);
};
class Gene {
public:
int start, stop;
string strandID, genes;
void setValues(string locs, string strand, string spcGene);
};
void Window::setValues(string locs, string strand, string a_length, string avg) {
locations = locs;
vector<string> token(3);
istringstream iss(locs);
for (int i=0; i<3; i++) {
getline(iss, token[i], '.');
}
start = atoi(token[0].c_str());
stop = atoi(token[2].c_str());
strandID = strand;
length = atoi(a_length.c_str());
average = atof(avg.c_str());
}
void Gene::setValues(string locs, string strand, string givenGene) {
vector<string> token(3);
istringstream iss(locs);
for (int i=0; i<3; i++) {
getline(iss, token[i], '.');
}
start = atoi(token[0].c_str());
stop = atoi(token[2].c_str());
strandID = strand;
genes = givenGene;
}
int getSize(string inputID, string strandID, const int header);
void getWindows(vector<Window> &win, string inputID, const int header);
void getGenes(vector<Gene> &posGene, vector<Gene> &negGene, string inputID, const int header);
void getSpecialWindows(vector<Window> &w, vector<Gene> &g, int wSize, int gSize, ofstream &output);
#endif /* defined(__Compare_Data_C____comp_fns__) */
Duplicate symbols means the linker faces the same function in both of your compilation units (main.cpp and comp_fns.cpp). Maybe you implemented the functions in the header without inline?
I've got at some code that should be recursively covering all positions on a boggle board. But for some reason it throws a segmentation fault after finding only 2 words? Any ideas why that would happen?
The code probably throwing the fault:
//++++++++++++ Find Word ++++++++++++++//
void findword(vector<vector<tile> > board, unsigned int row, unsigned int col, set<string> &results, unsigned int board_width, string word, set<string> dictionary)
{
if(checkbound(row, col, board_width) == false) // If tile is outside of the boundary than do nothing
return;
if(board[row][col].getused() == true) // If tile has already been used than do nothing
return;
word = word + board[row][col].getvalue(); // Adds letter to word
//Check Prefixes
set<string>::iterator pos;
pos = dictionary.lower_bound(word); // Creates an iterator at position
if(pos== dictionary.end()) // If it reaches the end without finding word than do nothing
{
return;
}
else if(word == pos->substr(0,word.length()))
{
cout<<"word: " <<word<<endl;
cout<<"dict: " <<*pos<<endl;
if(word == *pos) // If word = word at prefix
{
cout<< word<<" word inserted"<<endl;
results.insert(word); // Add words to results set
}
}
else
return;
//set to used
board[row][col].setused(true); // set tile to used
findword(board, row-1, col-1, results, board_width, word, dictionary); // Checks all tiles around every tile
findword(board, row-1, col, results, board_width, word, dictionary);
findword(board, row-1, col+1, results, board_width, word, dictionary);
findword(board, row, col-1, results, board_width, word, dictionary);
findword(board, row, col+1, results, board_width, word, dictionary);
findword(board, row+1, col-1, results, board_width, word, dictionary);
findword(board, row+1, col, results, board_width, word, dictionary);
findword(board, row+1, col+1, results, board_width, word, dictionary);
board[row][col].setused(false); // set tile to not-used
}
Error given:
word: r
dict: riot
word: ro
dict: robot
word: rob
dict: robot
word: robo
dict: robot
word: robot
dict: robot
robot word inserted
word: roo
dict: root
word: root
dict: root
root word inserted
Segmentation fault (core dumped)
Valgrind's main error code:
==4629== Invalid read of size 1
==4629== at 0x407C2E: tile::getused() (tile.cpp:33)
==4629== by 0x401ACE: findword(std::vector<std::vector<tile, std::allocator<tile> >, std::allocator<std::vector<tile, std::allocator<tile> > > >, unsigned int, unsigned int, std::set<std::string, std::less<std::string>, std::allocator<std::string> >&, unsigned int, std::string, std::set<std::string, std::less<std::string>, std::allocator<std::string> >) (main.cpp:58)
==4629== by 0x4020EC: findword(std::vector<std::vector<tile, std::allocator<tile> >, std::allocator<std::vector<tile, std::allocator<tile> > > >, unsigned int, unsigned int, std::set<std::string, std::less<std::string>, std::allocator<std::string> >&, unsigned int, std::string, std::set<std::string, std::less<std::string>, std::allocator<std::string> >) (main.cpp:93)
==4629== by 0x4020EC: findword(std::vector<std::vector<tile, std::allocator<tile> >, std::allocator<std::vector<tile, std::allocator<tile> > > >, unsigned int, unsigned int, std::set<std::string, std::less<std::string>, std::allocator<std::string> >&, unsigned int, std::string, std::set<std::string, std::less<std::string>, std::allocator<std::string> >) (main.cpp:93)
==4629== by 0x401F78: findword(std::vector<std::vector<tile, std::allocator<tile> >, std::allocator<std::vector<tile, std::allocator<tile> > > >, unsigned int, unsigned int, std::set<std::string, std::less<std::string>, std::allocator<std::string> >&, unsigned int, std::string, std::set<std::string, std::less<std::string>, std::allocator<std::string> >) (main.cpp:91)
==4629== by 0x402264: findword(std::vector<std::vector<tile, std::allocator<tile> >, std::allocator<std::vector<tile, std::allocator<tile> > > >, unsigned int, unsigned int, std::set<std::string, std::less<std::string>, std::allocator<std::string> >&, unsigned int, std::string, std::set<std::string, std::less<std::string>, std::allocator<std::string> >) (main.cpp:95)
==4629== by 0x402BF0: main (main.cpp:185)
==4629== Address 0x4c3b178 is 8 bytes after a block of size 48 alloc'd
The Checkbound function:
//+++++++++++ Check Bounds ++++++++++++//
bool checkbound(unsigned int row, unsigned int col, unsigned int board_width)
{
if(row < 0 || row > board_width || col < 0 || col > board_width)
return false;
else
return true;
}
board:
r b o
o i t
r o h
What value of board_width? If this is 3, then you forgot that indexing starting from 0 and maximum available index is 2, so condition in checkbound function must be:
if(row < 0 || row >= board_width || col < 0 || col >= board_width)
My guess is that your problem is in your checkbound function. You do the following:
row > board_width
I'm not sure how you're counting the width, but I believe your problem is here. A vector with a size of 3 will be the indices:
myVec[0], myVec[1], myVec[2].
If in this example, you are saying the board_width is 3, this will cause your segfault.
recently I decide to debug my application with valgrind.
I've resolved a lot of errors, but can't this one.
==12205== Invalid read of size 8
==12205== at 0x37E1864C40: std::_Rb_tree_increment(std::_Rb_tree_node_base*) (in /usr/lib64/libstdc++.so.6.0.8)
==12205== by 0x40393C: readConfig(std::string) (stl_tree.h:257)
==12205== by 0x4058BE: main (application.cpp:42)
==12205== Address 0x5589b88 is 24 bytes inside a block of size 48 free'd
==12205== at 0x4A05A33: operator delete(void*) (vg_replace_malloc.c:346)
==12205== by 0x4067AD: std::_Rb_tree<std::string, std::pair<std::string const, std::string>, std::_Select1st<std::pair<std::string const, std::string> >, std::less<std::string>, std::allocator<std::pair<std::string const, std::string> > >::erase(std::_Rb_tree_iterator<std::pair<std::string const, std::string> >, std::_Rb_tree_iterator<std::pair<std::string const, std::string> >) (new_allocator.h:94)
==12205== by 0x406841: std::_Rb_tree<std::string, std::pair<std::string const, std::string>, std::_Select1st<std::pair<std::string const, std::string> >, std::less<std::string>, std::allocator<std::pair<std::string const, std::string> > >::erase(std::string const&) (stl_tree.h:1215)
==12205== by 0x403934: readConfig(std::string) (stl_map.h:461)
==12205== by 0x4058BE: main (application.cpp:42)
Part of my code:
string config_file;
if (strlen(getParam("config") . c_str()) > 0)
{
config_file = getParam("config");
}
else
config_file = string("default.conf");
if (access(config_file . c_str(), 0) == -1)
{
printf("Config file \"%s\" not exists\n", config_file . c_str());
exit(1);
}
if (!readConfig(config_file))
{
printf("Application error: read config file\n");
exit(1);
}
String #42:
if (!readConfig(config_file))
Please try to help me.
Thanks in advance!
Update #1:
I apologize for so large function :(
bool readConfig(string filename)
{
time_t rawtime;
struct tm * timeinfo;
time ( &rawtime );
timeinfo = localtime ( &rawtime );
map<string,string> tmp_buff;
ifstream ifs( filename.c_str() );
string temp,tmp;
int i;
unsigned int MAX_MATCH = 40;
regex_t re;
char *pattern = "([^=]+)=(.+)";
const char* s;
map<int,string> matches_tmp;
map<string,string>::const_iterator it;
char s1[1024];
size_t rm;
regmatch_t pmatch[MAX_MATCH];
regcomp(&re, pattern, REG_ICASE|REG_EXTENDED|REG_NOSUB);
if ((rm = regcomp (&re, pattern, REG_EXTENDED)) != 0)
{
printf("Invalid expression:'%s'\n",pattern);
return false;
}
int start[2]={0},end[2]={0},current[2]={0};
char * b;
string substr;
bool start_time=false,inside_time=false,error=false;
while( getline( ifs, temp ) )
{
tmp=trim(temp);
tmp=temp;
if(strlen(tmp.c_str())==0) continue;
s=tmp.c_str();
if(!regexec(&re, s, MAX_MATCH, pmatch, 0))
{
for(i=1;i<=2;i++)
{
strncpy (s1, s + pmatch[i].rm_so, pmatch[i].rm_eo - pmatch[i].rm_so);
s1[pmatch[i].rm_eo - pmatch[i].rm_so] = '\0';
matches_tmp[i]=trim((string)s1);
}
if(matches_tmp[1]==string("start-time"))
{
substr=matches_tmp[2].substr(0,2);
b=new char[substr.length()+1];
strcpy(b, substr.c_str() );
if(strlen(b)!=2) continue;
start[0]=atoi(b);
//free(b);
substr=matches_tmp[2].substr(3,2);
b=new char[substr.length()+1];
strcpy(b, substr.c_str() );
if(strlen(b)!=2) continue;
start[1]=atoi(b);
start_time=true;
continue;
}
if(matches_tmp[1]==string("end-time"))
{
start_time=false;
substr=matches_tmp[2].substr(0,2);
b=new char[substr.length()+1];
strcpy(b, substr.c_str() );
if(strlen(b)!=2) error=true;
end[0]=atoi(b);
substr=matches_tmp[2].substr(3,2);
b=new char[substr.length()+1];
strcpy(b, substr.c_str() );
if(strlen(b)!=2) error=true;
end[1]=atoi(b);
if(error)
{
printf("ERROR1\n");
error=false;
continue;
}
current[0]=timeinfo->tm_hour;
current[1]=timeinfo->tm_min;
if(end[0]<start[0])
{
if(
(current[0]<start[0] && current[0]>end[0]) ||
(current[0]==start[0] && current[1]<start[1]) ||
(current[0]==end[0] && current[1]>end[1])
)
{
error=true;
}
}else
{
if(
(current[0]<start[0]) ||
(current[0]>start[0] && current[0]>end[0]) ||
(current[0]==start[0] && current[1]<start[1]) ||
(current[0]==end[0] && current[1]>end[1])
)
{
error=true;
}
}
if(error)
{
error=false;
continue;
}
for (it = tmp_buff.begin(); it != tmp_buff.end(); ++it)
{
if(config.find( it->first ) != config.end()) config.erase(it->first);
config[it->first]=it->second;
tmp_buff.erase(it->first);
}
}
if(strlen(matches_tmp[1].c_str())==0) continue;
if(start_time)
{
tmp_buff[matches_tmp[1]]=matches_tmp[2];
}
else
config[matches_tmp[1]]=matches_tmp[2];
}
}
}
I suppose you are incrementing an invalid std::set or std::map iterator. This incorrect program produces a similar valgrind error:
#include <set>
int main () {
std::set<int> s;
s.insert(1);
s.insert(2);
s.insert(3);
for(std::set<int>::iterator it = s.begin(); it != s.end(); ++it) {
if(*it == 2) s.erase(it);
}
}
EDIT: Yep, you are doing exactly what I said:
for (it = tmp_buff.begin(); it != tmp_buff.end(); ++it)
{
if(config.find( it->first ) != config.end()) config.erase(it->first);
config[it->first]=it->second;
tmp_buff.erase(it->first);
}
The call to tmp_buff.erase(it->first) invalidates it. But, you subsequently increment it: ++it. This is not allowed.
Also, there is no reason to call config.erase. The entry in config will be implicity destroyed when it is overwritten in the next line. Try:
for (it = tmp_buff.begin(); it != tmp_buff.end(); ++it)
{
config[it->first]=it->second;
}
tmp_buff.clear();