// created a copy of CNode and added the new value
CNode *copyCNode = new CNode;
//memcpy(c, iNode->mainNode->cNode, sizeof(*(iNode->mainNode->cNode)) );
memcpy(copyCNode, iNode->mainNode->cNode, sizeof(CNode) );
CNode *updated_cnode = inserted(copyCNode, b, index);
std::cout << "temporay CNode created : " << updated_cnode->branch[index]->sNode->value << std::endl;
if(memcmp(copyCNode, iNode->mainNode->cNode, sizeof(CNode)) == 0){
std::cout << "mainNode is not changed " << std::endl ;
}else{
std::cout << "mainNode is changed" << std::endl;
}
bool cas_ret = __sync_bool_compare_and_swap(&iNode->mainNode->cNode, copyCNode, updated_cnode);
std::cout << "return cas_ret : " << cas_ret << std::endl;
if(cas_ret){
std::cout << "New added value " << iNode->mainNode->cNode->branch[index]->sNode->value << std::endl;
return 0; // successfully attached the node
}
else{
return 1;
}
The above code is part of my code base.
There is no compilation error and the code is running fine.
But __sync_bool_compare_and_swap function always return false in my code. Even before the CAS function call I did the memory comparison (memcpy) and its showing that both the arguments are equal, in that case CAS should swap the value with third argument, but it is not.
copyCNode -> Holds the copy value of iNode->mainNode->cNode
updated_cnode -> Holds the updated value of iNode->mainNode->cNode (New branch added)
Please suggest any solution.
Thanks
The CAS operation failed because: iNode->mainNode->cNode ≠ copyCNode. It doesn't matter that their contents are both the same. The CAS operation is trying to do:
if (iNode->mainNode->cNode == copyCNode) {
iNode->mainNode->cNode = updated_cnode;
return true;
}
return false;
All you verified is that *copyCnode = *iNode->mainNode->cNode, which is not what the CAS operation is interested in.
I got the solution.
I think I should not create the memory for copyNode. Instead, I should just copyNode = iNode->mainNode->cNode and the rest code is working good.
Thanks #jxh
Related
I am using the dladdr from libld (http://linux.die.net/man/3/dladdr) to get a trace of the function calls. Here it is minimal example with a single traced element:
#include<iostream>
#include <dlfcn.h> // link with -ldl -rdynamic a
void f(){
void **frame = static_cast<void **>(__builtin_frame_address(0));
void **bp = static_cast<void **>(*frame);
void *ip = frame[1];
Dl_info info;
dladdr(ip, &info);
std::cout << info.dli_sname << " " << info.dli_fname << " " << info.dli_saddr << std::endl;
ip = bp[1];
bp = static_cast<void**>(bp[0]);
dladdr(ip, &info);
std::cout << info.dli_sname << " " << info.dli_fname << " " << info.dli_saddr << std::endl;
}
int main(){
f();
}
which outputs:
main ./a.out 0x402800
__libc_start_main /lib64/libc.so.6 0x7febf6bf2610
that is, Dl_info has the traced function name, the compiled file where it belongs and some address (0x7f...) described in the man page as "Exact address of symbol named".
This address has information of the source file location (from where the function has been called). In fact with the help of some utility I can get that information:
$ addr2line -e a.out
/home/user/test.cpp:34
(give the exact line where main is defined in source file). And this works as long as the program was compiled with the -g option.
Now what I want is to extract this information programmaticaly. Supposedly, this is possible with the BFD library.
This is my attempt, based on BFD examples found for example here: http://opensource.apple.com/source/X11libs/X11libs-40.2/cairo/cairo-1.8.6/util/backtrace-symbols.c
1) first I have to define a function find_addr_sect that will be called by bfd_map_over_sections (through a pointer) later.
static void find_addr_sect(bfd *abfd, asection *section, void *obj){
bfd_data *data = (bfd_data *)obj;
bfd_vma vma;
bfd_size_type size;
if (data->found)
return;
if (!(bfd_get_section_vma(abfd, section)))
return;
vma = bfd_get_section_vma(abfd, section);
if (data->pc < vma)
return;
size = bfd_get_section_size(section);
if (data->pc >= vma + size)
return;
data->found = bfd_find_nearest_line(abfd, section, syms,
data->pc - vma,
&data->filename,
&data->function,
&data->line);
}
2) I put the code directing inside the function (this replaces the function void f() above.
void f(){
void **frame = static_cast<void **>(__builtin_frame_address(0));
void **bp = static_cast<void **>(*frame);
void *ip = frame[1];
Dl_info info;
dladdr(ip, &info);
std::cout << info.dli_sname << " " << info.dli_fname << " " << info.dli_saddr << std::endl;
////////////////////
// this will try to find the location of main (first in the stack)
bfd *abfd = bfd_openr(info.dli_fname, NULL); assert(abfd); // the executable file is opened successfully
// bfd_data data;
bfd_map_over_sections(abfd, find_addr_sect, nullptr); // !! doesn't call `find_addr_sect` at all.
///////////////////
ip = bp[1];
bp = static_cast<void**>(bp[0]);
dladdr(ip, &info);
std::cout << info.dli_sname << " " << info.dli_fname << " " << info.dli_saddr << std::endl;
}
Sadly, I am stuck here because the bfd_map_over_sections call doesn't do anything. I am using bfd_map_over_sections in the wrong way, why?
Sorry for using C++, in this is a C question. It shortens most of my code and I am more used to it.
EDIT: I added this lines and I can confirm that one clue of the problem is that the number of sections is zero.
unsigned int numSections = -1;
numSections = bfd_count_sections(abfd);
std::cout << "num sections " << numSections << std::endl; // gives "0"
I looked for more examples, it seems that I was missing two things, calling the function bfd_check_format after opening and also populating and passing the address information in the bfd_data structure.
...
bfd *abfd = bfd_openr(info.dli_fname, NULL); assert(abfd);
// char **matching;
// bfd_data data;// = (bfd_data *)obj;
if (!bfd_check_format (abfd, bfd_object)){
bfd_close (abfd); assert(0);
}
...
later bfd_data variable is used as input and output of the find_addr_sect. Therefore
...
bfd_data data;// = (bfd_data *)obj;
data.pc = (bfd_hostptr_t)info.dli_saddr;
data.found = FALSE;
bfd_map_over_sections(abfd, find_addr_sect, &data);
...
And now it works.
i have loop to display a table with buttons.
WTable *my_table = new WTable();
int row = 0; vector<WPushButton*> buttons;
for ( vector<map<string, string> >::iterator it = data.begin(); it != data.end(); it++ ) {
buttons[row] = new WPushButton("E");
my_table->elementAt( row, 0 )->addWidget( buttons[row] );
buttons[row]->clicked().connect( boost::bind( &this->process, WString::tr( (*it)["id"] ) ) );
row++;
}
......
function ClassName::process( Wstring *str ){
cout << str << endl;
}
the problem is on the binding of signal.
how to connect looped buttons signals to a function?
It looks like the signature of process() does not matcht the argument you try to bind to it: WString vs WString *. Does it work with
void ClassName::process( Wstring str ){
cout << str << endl;
}
Good day. I could really use your help on this one. I have a stats text file in the following format.
ID=1000000
Name=Name1
Field1=Value1
...(Fields 2 to 25)
Field26=Value26
ID=1000001
Name=Name2
Field1=Value1
...(Fields 2 to 25)
Field26=Value26
ID=1000002
Name=Name2
Field1=Value1
...(Fields 2 to 25)
Field26=Value26
...goes up to 15000
I have an active people text file separated by line breaks.
Name2
Name5
Name11
Name12
...goes up to 1400 Random Names
I need to be able to delete records from the stats text file (ID, Name, Fields1 to 26) if the name is not found in the active people text file. In the example above, the associated record for Name1(ID, Name, Fields1 to 26) should be deleted since it's not in the active people text file.
I've tried reformatting the stats file through notepad++ using TextFX->Quick->Find/Replace to convert it to a comma separated file with each record separated by a line break. I had it rearranged to
ID Name Field1 ...Fields2 to Fields 25... Field26
1000000 Name1 Value1 ...Value2 to Value 25... Value26
1000001 Name2 Value1 ...Value2 to Value 25... Value26
1000002 Name2 Value1 ...Value2 to Value 25... Value26
I've opened it with excel and I've created two tables (stats table and a active names table) in mysql using the csv file file. I'm not sure how to process this in an automatic function. Besides removing inactive records, the other problem I have is rewriting it back to its old format.
I've been trying my best to figure this out for a hours on end. Is there a solution that won't require me to use find, copy, paste and switch between the two files 1400 times? Unfortunately, I have to keep the stats file in this format.
Please help. Thank you.
Here's a C++ program that will process the files for you:
#include <algorithm>
#include <fstream>
#include <iostream>
#include <locale>
#include <set>
#include <string>
#include <vector>
//trim functions taken:
//http://stackoverflow.com/questions/216823/whats-the-best-way-to-trim-stdstring/217605#217605
//with a slight change because of trouble with ambiguity
static int myIsSpace(int test)
{
static std::locale loc;
return std::isspace(test,loc);
}
static std::string &rtrim(std::string &s) {
s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(myIsSpace))).base(), s.end());
return s;
}
static std::string <rim(std::string &s) {
s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(myIsSpace))));
return s;
}
static std::string &trim(std::string &s) {return ltrim(rtrim(s));}
int main(int argc,char * argv[])
{
std::ifstream peopleFile;
peopleFile.open("people.txt");
if (!peopleFile.is_open()) {
std::cout << "Could not open people.txt" << std::endl;
return -1;
}
std::set<std::string> people;
while (!peopleFile.eof()) {
std::string somePerson;
std::getline(peopleFile,somePerson);
trim(somePerson);
if (!somePerson.empty()) {
people.insert(somePerson);
}
}
peopleFile.close();
std::ifstream statsFile;
statsFile.open("stats.txt");
if (!statsFile.is_open()) {
std::cout << "could not open stats.txt" << std::endl;
return -2;
}
std::ofstream newStats;
newStats.open("new_stats.txt");
if (!newStats.is_open()) {
std::cout << "could not open new_stats.txt" << std::endl;
statsFile.close();
return -3;
}
size_t totalRecords=0;
size_t includedRecords=0;
bool firstRecord=true;
bool included=false;
std::vector<std::string> record;
while (!statsFile.eof()) {
std::string recordLine;
getline(statsFile,recordLine);
std::string trimmedRecordLine(recordLine);
trim(trimmedRecordLine);
if (trimmedRecordLine.empty()) {
if (!record.empty()) {
++totalRecords;
if (included) {
++includedRecords;
if (firstRecord) {
firstRecord=false;
} else {
newStats << std::endl;
}
for (std::vector<std::string>::iterator i=record.begin();i!=record.end();++i) {
newStats << *i << std::endl;
}
included=false;
}
record.clear();
}
} else {
record.push_back(recordLine);
if (!included) {
if (0==trimmedRecordLine.compare(0,4,"Name")) {
trimmedRecordLine=trimmedRecordLine.substr(4);
ltrim(trimmedRecordLine);
if (!trimmedRecordLine.empty() && '='==trimmedRecordLine[0]) {
trimmedRecordLine=trimmedRecordLine.substr(1);
ltrim(trimmedRecordLine);
included=people.end()!=people.find(trimmedRecordLine);
}
}
}
}
}
if (!record.empty()) {
++totalRecords;
if (included) {
++includedRecords;
if (firstRecord) {
firstRecord=false;
} else {
newStats << std::endl;
}
for (std::vector<std::string>::iterator i=record.begin();i!=record.end();++i) {
newStats << *i << std::endl;
}
included=false;
}
record.clear();
}
statsFile.close();
newStats.close();
std::cout << "Wrote new_stats.txt with " << includedRecords << " of the " << totalRecords << ((1==totalRecords)?" record":" records") << "found in stats.txt after filtering against the " << people.size() << ((1==people.size())?" person":" people") << " found in people.txt" << std::endl;
return 0;
}
I'm trying to use SQLite's C API to open a database and access some records. It seems to open the database fine, but I don't get any results when trying a query (0 rows returned). The same query works in the sqlite3 CLI and other sqlite apps/frontends. I'm using [http://www.sqlite.org/cintro.html] as a reference.
My code is pretty much just two function calls. Program output is:
"Opened DB"
"number of rows = 0".
I'm not doing anything complicated here, so I hope I'm just making a simple mistake somewhere that I don't see. I'd appreciate any help.
-kf
int main()
{
// declare some vars
sqlite3* db_handle;
char sql[2048]; // for commands,queries and such
char* err_msg;
char** results;
int rows, columns;
// connect to database file
if (!(sqlite3_open_v2("../../Downloads/maps/ontario.sql", &db_handle, SQLITE_OPEN_READONLY, NULL)))
{
std::cerr << "Could not connect to DB" << std::endl;
std::cerr << "Error: " << sqlite3_errmsg(db_handle);
sqlite3_close(db_handle);
return -1;
}
else
{ std::cerr << "Opened DB" << std::endl; }
// try sending query
strcpy(sql, "SELECT * FROM osm_node_tags LIMIT 10");
if(!(sqlite3_get_table(db_handle, sql, &results, &rows, &columns, &err_msg)))
{
std::cerr << "Error: " << sqlite3_errmsg(db_handle);
sqlite3_close(db_handle);
return -1;
}
else
{
std::cerr << "number of rows = " << rows;
for (int i=1; i <= rows; i++)
{ std::cerr << results[(i * columns) + 0] << std::endl; }
}
return 1;
}
http://ray.bsdart.org/man/sqlite/c3ref/open.html
sqlite3_open_v2 returns SQLITE_OK (which is zero) when it's successful. I think your conditionals are upside-down.
I cannot even see any not-so-obvious bugs, so will note that sqlite3_get_table says:
This is a legacy interface that is preserved for backwards compatibility. Use of this interface is not recommended.
but it really shouldn't be broken. Have you double-checked that the table actually contains more than zero rows?
This should be simple (I'm just learning boost so I'm missing something)
I have read in some simple JSON using json_read and now have a ptree. All the examples on the web show using ptree.get("entry_name") to obtain an entry. All I want to do is something like:
ptree pt;
read_json(ss,pt);
BOOST_FOREACH(ptree::value_type &v, pt)
{
std::cout << v.{entry_name} << v.{value}
}
i.e. loop through the ptree and write out each name (i.e. what you put into pt.get()) and it's corresponding value.
Sorry if this is simple
Ross
I was searching the same thing, and couldn't find the answer anywhere. It turned out to be pretty simple indeed:
ptree pt;
/* load/fill pt */
for(iterator iter = pt.begin(); iter != pt.end(); iter++)
{
std::cout << iter->first << "," << iter->second.data() << std::endl;
}
iter->first is the entry name, and iter->second.data() is the entry value of the first level. (You can then re-iterate with iter->second.begin()/end() for deeper levels.)
Further, if one such node in this iteration is not a terminal node and is itself a ptree, you can get that as ptree from this iterator itself :
ptree subPt = iter->second.get_child("nodeName");
I'm having troubles with ptree as well, but perhaps this can help:
Check out boost's ptree quick tutorial
v.{entry_name}
would be
v.first
and
v.{value}
v.second.data()
Would that work?
Here's a great example of how to iterate a ptree using BOOST_FOREACH
http://akrzemi1.wordpress.com/2011/07/13/parsing-xml-with-boost/
for direct access using the normal "get" functions look at the example from boost:
http://www.boost.org/doc/libs/1_51_0/doc/html/boost_propertytree/tutorial.html
the documentation page is located here:
http://www.boost.org/doc/libs/1_51_0/doc/html/boost/property_tree/basic_ptree.html
I know its not very well documented but it is helpful.
Old thread, but here's a C++11 version of mr_georg's answer with range-based for loops:
ptree pt;
/* load/fill pt */
for(auto pair : pt)
{
std::cout << pair.first << "," << pair.second.data() << std::endl;
}
For this json:
{
"key1":"value1",
"key2":"value2"
}
It outputs:
key1,value1
key2,value2
This example iterates over a simple JSON object and puts its values into a vector.
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/lexical_cast.hpp>
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
int main (void)
{
try
{
std::stringstream ss;
std::string json_obj_str = "{ \"unit_1\": 1, \"unit_2\": 2, \"unit_3\": 3 }";
std::vector <float> fvec;
ss << json_obj_str; // put string into stringstream
boost::property_tree::ptree pt;
boost::property_tree::read_json(ss, pt); // put stringstream into property tree
// iterate over JSON properties
for (boost::property_tree::ptree::iterator iter = pt.begin(); iter != pt.end(); iter++)
{
std::cout << iter->first << ": " << iter->second.data() << std::endl;
fvec.push_back(boost::lexical_cast<float>(iter->second.data()));
}
for (size_t i = 0; i < fvec.size(); i++)
{
std::cout << "fvec.at(" << i << ") = " << fvec.at(i) << std::endl;
}
}
catch (const boost::property_tree::ptree_error &e)
{
std::cerr << "property_tree error = " << e.what() << std::endl;
return -2;
}
catch (std::exception const& e)
{
std::cerr << "exception = " << e.what() << std::endl;
return -1;
}
return 0;
}