Crash in C++ std::map - c++

I think I have isolated crash which happens only on cygwin platform. Tried to run with valgrind on linux — no effect, it reports no memory errors. I have function to remove zero monomes from Polynomes
typedef map<multiset<int>, double> Polynome;
void removeZeroes(Polynome&p){
for(auto it=p.cbegin();it!=p.cend();){
if(p[it->first]==0.) {
p.erase(it++);
} else ++it;
}
}
void calcGDerivatives(Reduced &r) {
auto vars = getAllVars(r);
cout<<"calculating derivatives"<<endl;
iterate(vars, [&r](multiset<int>k1)->void {
if (r.grandDerivatives.count(k1)) return;
Polynome der = r.grandDerivatives[k1];
for (auto &kv : r.grandPoly) {
Monome monDer = monomeDeriv(kv.first, k1);
multiset<int> p = kv.first;
if (monDer.first == 0) continue;
monDer.first *= kv.second;
add(der, monDer);
}
removeZeroes(der);
r.grandDerivatives[k1]=der; //since der is a copy
});
}
If I replace Polynome der to reference &der and remove r.gr..[k1]=der, then I get a crash. Is it unsafe to modify std::map's value? How can I find a place were problem happens? Thanx!

I've finally found true cause of the problem. One of my functions looked like this:
stl::vector<...> f(){
// do something
// forgot return
}
f();
This immediately gives a crash on cygwin.

Related

How to use F.getValueSymbolTable()

I wanna get all the local variables in a function.
void getLocalVariables(Function &F) {
ValueSymbolTable *vst = F.getValueSymbolTable();
for (auto vs : vst) { // here it says: This scope-based "for" statement required the appropriate "begin" function, but was not found
auto s = vs.getKey();
auto v = vs.getValue();
}
}
The error is that: This scope-based "for" statement required the appropriate "begin" function, but was not found. So how can I correct my code? Tks.
I check the documentation for ValueSymbolTable, and finally find how to use it. But actually, as arnt said, they are not local variables in source code. They are temporary variables generated by IR.
void getLocalVariables(Function &F) {
// not test yet
ValueSymbolTable *vst = F.getValueSymbolTable();
errs() << (*vst).size() << "\n.";
for (ValueSymbolTable::iterator VI = vst->begin(), VE = vst->end(); VI != VE; ++VI) {
Value *V = VI->getValue();
if (!isa<GlobalValue>(V) || cast<GlobalValue>(V)->hasLocalLinkage()) {
if (!V->getName().startswith("llvm.dbg"))
// Set name to "", removing from symbol table!
V->setName("");
}
}
}

JsonCPP throwing a logic error:requires objectValue or nullValue

void exp::example(std::string &a, std::string &b)
{
if (m_root.isObject() && m_root.isMember(a))
{
if (m_root[a].isMember(b))
{
m_root[a].append(b);
}
}
else
{
m_root[a] = Json::arrayValue;
m_root[a].append(b);
}
}
(m_root is defind in the hpp)
When I'm running this code I get the logic error:
in Json::Value::find(key, end, found): requires objectValue or nullValue.
I found out that I got this error from this if:
if (m_root[a].isMember(b))
I don't understand why do I get this error there, I used the same function in the if above him and I didn't get this error.
P.S the function is working until it enter the nested if, example:
a
b
m_root
"hey"
"a1"
{"hey":["a1"]}
"bye"
"a2"
{"hey":["a1"], "bye":["b1"]}
"cye"
"a3"
{"hey":["a1"], "bye":["b1"], "cye":["a3"]}
"hey"
"a4"
error: in Json::Value::find(key, end, found): requires objectValue or nullValue
I get the error only in the 4th call.
I appreciate your help!
On the 4th iteration you access the m_root["hey"] object which is of type arrayValue. Those values are not supported by the isMember method.
You'll have to find the value in the array in another way. I suggest iterating over the array, in something like:
bool is_inside_array(const Json::Value &json_array, const string& value_to_find)
{
for (const Json::Value& array_value: json_array) {
if (array_value.asString() == value_to_find) {
return true;
}
}
return false;
}
Then replace the inner if with:
if (is_inside_array(m_root[a], b))

g++ optimization makes the program unable to run

I implemented a path planning algorithm based on D*-Lite. When I do not turn on optimization (-O0), the program can run normally. But when I turn on the optimization level (-O1/2/3), the program cannot be terminated. In Visual Studio, both debug mode and release mode can run normally. In the above cases, the codes are the same.I don’t know how to find the problem, can anyone help me?
class DstarLite {
public:
DstarLite() = delete;
DstarLite(GridStatus* a, GridStatus* b, FILE* fp)
: k_m_(0), start_(a), last_(start_), goal_(b), open_close_(fp) {}
void calculateKey(GridStatus* s);
void updateVertex(GridStatus* u);
void initialize();
void computeShortestPath();
void rePlanning(vector<pair<GridStatus*, int>>& node_change);
GridStatus* getStart();
void setStart(GridStatus* val);
GridStatus* getGoal();
private:
Fib frontier_;
double k_m_;
unordered_map<GridStatus*, handle_t>
heap_map_;
GridStatus* start_;
GridStatus* last_;
GridStatus* goal_;
FILE* open_close_;
};
void DstarLite::calculateKey(GridStatus* s) {
s->f = min(s->g, s->rhs) + heuristic(start_, s) + k_m_;
s->k2 = min(s->g, s->rhs);
}
void DstarLite::initialize() {
fprintf(open_close_, "%d %d\n", start_->x, start_->y);
fprintf(open_close_, "%d %d\n", goal_->x, goal_->y);
goal_->rhs = 0;
calculateKey(goal_);
handle_t hand = frontier_.push(goal_);
heap_map_[goal_] = hand;
}
void DstarLite::updateVertex(GridStatus* u) {
bool heap_in = heap_map_.find(u) != heap_map_.end();
if (u->g != u->rhs && heap_in) {
calculateKey(u);
frontier_.update(heap_map_[u]);
} else if (u->g != u->rhs && !heap_in) {
calculateKey(u);
handle_t hand = frontier_.push(u);
heap_map_[u] = hand;
} else if (u->g == u->rhs && heap_in) {
calculateKey(u);
frontier_.erase(heap_map_[u]);
heap_map_.erase(u);
}
}
void DstarLite::computeShortestPath() {
int count = 0;
while (smaller(frontier_.top(), start_) || !myEqual(start_->rhs, start_->g)) {
count++;
auto u = frontier_.top();
pair<double, double> k_old = {u->f, u->k2};
pair<double, double> k_new;
k_new.first = min(u->g, u->rhs) + heuristic(start_, u) + k_m_;
k_new.second = min(u->g, u->rhs);
if (k_old < k_new) {
calculateKey(u);
frontier_.update(heap_map_[u]);
} else if (myGreater(u->g, u->rhs)) {
u->g = u->rhs;
frontier_.pop();
heap_map_.erase(u);
for (auto s : neighbors(u)) {
if (s->rhs > u->g + cost(u, s)) {
s->next = u;
s->rhs = u->g + cost(u, s);
updateVertex(s);
}
}
} else {
double g_old = u->g;
u->g = kDoubleInfinity;
auto neighbor = neighbors(u);
neighbor.push_back(u);
for (auto s : neighbor) {
if (myEqual(s->rhs, cost(s, u) + g_old)) {
if (!equal(s, goal_)) {
double pp_s = kDoubleInfinity;
for (auto succ : neighbors(s)) {
double dis = succ->g + cost(succ, s);
if (dis < pp_s) {
pp_s = dis;
s->next = succ;
}
}
s->rhs = pp_s;
}
}
updateVertex(s);
}
}
}
cout << "Dstar visited nodes : " << count << endl;
}
void DstarLite::rePlanning(vector<pair<GridStatus*, int>>& node_change) {
k_m_ += heuristic(last_, start_);
last_ = start_;
for (auto change : node_change) {
GridStatus* u = change.first;
int old_threat = u->threat;
int new_threat = change.second;
double c_old;
double c_new;
u->threat = new_threat;
u->rhs += (new_threat - old_threat) * threat_factor;
updateVertex(u);
for (auto v : neighbors(u)) {
u->threat = old_threat;
c_old = cost(v, u);
u->threat = new_threat;
c_new = cost(v, u);
if (c_old > c_new) {
if (v != goal_) {
if (v->rhs > u->g + c_new) {
v->next = u;
v->rhs = u->g + c_new;
}
}
} else if (myEqual(v->rhs, c_old + u->g)) {
if (v != goal_) {
double pp_s = kDoubleInfinity;
for (auto pre : neighbors(v)) {
double dis = pre->g + cost(pre, v);
if (dis < pp_s) {
pp_s = dis;
v->next = pre;
}
}
v->rhs = pp_s;
}
}
updateVertex(v);
}
}
}
GridStatus* DstarLite::getStart() { return start_; }
void DstarLite::setStart(GridStatus* val) { start_ = val; }
GridStatus* DstarLite::getGoal() { return goal_; }
DstarLite dstar(start, goal, open_close);
dstar.initialize();
dstar.computeShortestPath();
Sorry, I think it is difficult to locate the problem in the code, so the code was not shown before. Now I have re-edited the question, but there are a lot of codes, and the main calling part is computeShortest().
As you did not provide any code, we can give you only some general hints to fix such problems.
As a first assumption your code has definitely one or more bugs which causes what we call undefined behaviour UB. As the result is undefined, it can be anything and is often changing behaviour with different optimization levels, compiler versions or platforms.
What you can do:
enable really ALL warnings and fix them all! Look especially for something like "comparison is always...", "use of xxx (sometimes) without initialization", " invalid pointer cast", ...
try to compile on different compilers. You should also try to use gcc and/or clang, even on windows. It is maybe hard in the first time to get the environment for these compilers run on windows plattforms, but it is really worth to do it. Different compilers will give different warnings. Fixing all warnings from all compilers is a really good help!
you should use memory tracers like valgrind. I have not much experience on windows, but I believe there are also such tools, maybe already integrated in your development suite. These tools are really good in finding "of by x" access, access freed memory and such problems.
if you still run into such trouble, static code analyser tools may help. Typically not as much as managers believe, because today's compilers are much better by detecting flaws as expected by dinosaur programmers. The additional findings are often false positives, especially if you use modern C++. Typically you can save the money and take a class for your own education!
Review, Review, Review with other people!
snip the problem small! You should spend most of your development time by setting up good automated unit tests. Check every path, every function in every file. It is good to see at minimum 95% of all branches covered by tests. Typically these tests will also fail if you have UB in your code if you change optimizer levels and or compiler and platforms.
using a debugger can be frustrating. In high optimized code you jump through all and nothing and you may not really see where you are and what is the relation to your code. And if in lower optimizer level the bug is not present, you have not really much chance to see find the underlying problem.
last but not least: "printf debugging". But this may change the behaviour also. In worst case the code will run always if you add a debug output. But it is a chance!
use thread and memory sanitizers from your compiler.
The problem is caused by the comparison of floating-point numbers. I deliberately put aside this question when I wrote the code before :). Now it can operate normally after being fixed.

Segmentation fault bintree

I'm trying to implement the bintree, but I have problems in the insert method.
If I add the first element, the program dont crash but, when I introduce 2 or more element the program crash.
This is the code
template <typename T>
void Arbol<T>:: insertar( T c){
if(laraiz==0)
{
laraiz=new celdaArbol;
laraiz->elemento=c;
laraiz->padre=laraiz->hizqu=laraiz->hder=0;
}
else {
celdaArbol *com=laraiz;
bool poner=false;
while(poner==false){
if(c>com->elemento){
if(com->hder==0){
com->hder= new celdaArbol;
com->hder->elemento=c;
com->hder->padre=com;
poner=true;
}
else{
com=com->hder;
}
}
else {
if(com->hizqu==0){
com->hizqu= new celdaArbol;
com->hizqu->elemento=c;
com->hizqu->padre=com;
poner=true;
}
else {
com=com->hizqu;
}
}
}
}
}
I think that the problem is in the else:
else{
com=com->hizqu; //com=com->hder;
}
Because I saw in the debugger that the program enter several times in the section and should not do.
According to this code:
laraiz->padre=laraiz->hizqu=laraiz->hder=0;
You do not properly intialize pointers hizqu and hder to nullptr in constructor of celdaArbol class. And you do not initialize them in either branch of if(c>com->elemento){ so they seem to have garbage values.
Also your code can become more readable and less error prone if you use proper C++ constructions:
celdaArbol *com=laraiz;
while( true ){
celdaArbol *&ptr = c > com->elemento ? com->hder : com->hizqu;
if( ptr ) {
com = ptr;
continue;
}
ptr = new celdaArbol;
ptr->elemento=c;
ptr->padre=com;
ptr->hder = ptr->hizqu = nullptr;
break;
}
This code is logically equal to yours, except it shorter, easier to read, avoid duplication and fixes your bug.
For every leaf node (except the root of the tree), you never initialize the left child or right child node to be anything but an unspecified value.
You probably meant to initialize them as nullptr.
Here's one example:
if (com->hizqu==0){
com->hizqu = new celdaArbol;
com->hizqu->elemento = c;
com->hizqu->padre = com;
poner = true;
// What is the value of com->hizqu->hizqu?
// What is the value of com->hizqu->hder?
}

MISRA-C++:2008[8-4-3] : return in all exit path in function

When testing my code (static analysis) to see if i respect misra c++ 2008, i get the following error
Function does not return a value on all paths.
The function looks like
int* Dosomething(string v)
{
int* retvalue = NULL;
if( 0 == exists(v) )
{
throw("error: value doesn't exist");
}
else
{
retvalue = dosomecomputations(v);
}
return retvalue;
}
I really need to throw an exception, because depending of the error the caller shall do something. The possible list of errors can be big and it is not just that the value doesn't exist as in this sample of code.
How can i manage it? I think that in this case the tool i'm using should not see it as a non-compliance to misra.
Thanks for your advise.
rony.
The following code should not report any warnings/errors with MISRA C++ 2008 rules applied. So most likely it's an issue with your tool - or the posted code is not the affected part.
#include <string>
int exists(std::string v){ (void)v; return 1; }
int* dosomecomputations(std::string v){ (void)v; return NULL; }
int* dosomething(std::string v){
int* retvalue = NULL;
if( 0 == exists(v) ){
throw("error: value doesn't exist");
}else{
retvalue = dosomecomputations(v);
}
return retvalue;
}
Try to check just the snippet above with your MISRA checker and see if it's still reporting anything. If the problem persists I would just contact the toolvendor and ask him about that issue.