I am trying to make an element system for my GUI, but I have a problem!
I am calling CBaseElement::MakeTop() every time a mouseclick has been detected inside a window
void CBaseElement::MakeTop()
{
int nSize = g_pElementList.size();
for (int iIndex = 0; iIndex < nSize; iIndex++)
{
CBaseElement* pNode = g_pElementList[iIndex];
if (pNode == this)
{
g_pElementList.erase(g_pElementList.begin() + iIndex);
g_pElementList.push_back(this);
break;
}
}
}
But how do I let the cursor element be the last to be rendered and the tooltip to be second?
I have did this method:
void CBaseElement::MakeTop()
{
int nSize = g_pElementList.size();
for (int iIndex = 0; iIndex < nSize; iIndex++)
{
CBaseElement* pNode = g_pElementList[iIndex];
if (pNode == this)
{
g_pElementList.erase(g_pElementList.begin() + iIndex);
g_pElementList.push_back(this);
for (int iIndex2 = 0; iIndex2 < nSize; iIndex2++)
{
CBaseElement* pNode2 = g_pElementList[iIndex2];
if (pNode2->GetType() == ET_TOOLTIP || pNode2->GetType() == ET_CURSOR)
{
g_pElementList.erase(g_pElementList.begin() + iIndex2);
g_pElementList.push_back(pNode2);
break;
}
}
}
}
}
I need a better way of doing this.
Related
I was creating a custom operating system and I have a problem. I have an array of child components in an array of all opened windows. When I call a function CDraw (Component Draw) on the child array the system crashes with the message "General Protection Fault Detected".
Window array and code:
int openedWindows = 0;
Window* windows[128];
int OpenWindow(Window win) {
windows[0][openedWindows] = win;
openedWindows++;
return openedWindows-1;
};
void CloseWindow(int index) {
for(int i = index+1; i < 127; i++) {
if(i != 127)
windows[0][i] = windows[0][i-1];
else
windows[0][i] = Window();
}
openedWindows--;
};
void CloseAllWindows() {
for(int i = 0; i < 127; i++) {
windows[0][i] = Window();
}
openedWindows = 0;
};
/*Draw Windows*/
for(int i = 0; i < openedWindows; i++)
{
windows[0][i].Update();
}
Where I call the code:
Window wnd = Window("Window");
wnd.Update();
Button btn = Button(wnd, "Hello");
btn.CPosition = Point(10, 10);
btn.BackColor = Color(MediumTurquoise);
btn.parent = &wnd;
btn.parent->AddComponent(btn);
btn.Update();
Button btn2 = Button(wnd, "H2");
btn2.CPosition = Point(100, 100);
btn2.BackColor = Color(Red);
btn2.parent = &wnd;
btn2.parent->AddComponent(btn2);
btn2.Update();
OpenWindow(wnd);
Componet code:
int childIndex = 0;
BaseGuiComponent* children[128];
int BaseGuiComponent::AddComponent(BaseGuiComponent baseGuiComponent) {
children[0][childIndex] = baseGuiComponent;
childIndex++;
return childIndex-1;
};
void BaseGuiComponent::RemoveComponent(int index) {
for(int i = index+1; i < 127; i++) {
if(i != 127)
children[0][i] = children[0][i-1];
else
children[0][i] = BaseGuiComponent();
}
childIndex--;
};
void BaseGuiComponent::ClearComponents() {
for(int i = 0; i < 127; i++) {
children[0][i] = BaseGuiComponent();
}
childIndex = 0;
};
//List components and Update();
void BaseGuiComponent::DrawChildren() {
for(int i = 0; i < childIndex; i++) {
children[0][i].Update();
}
};
Drawing code:
void BaseGuiComponent::CDraw() {
if (strcmp(type,"Window",128)) {
Draw->DrawWindow(BackColor.GetHexColor(), CPosition.X, CPosition.Y, CSize.Width, CSize.Height, 2, CText, WindowStyle, Draw->GetScreenBounds());
DrawChildren();
} else if (strcmp(type,"Button",128)) {
Draw->FillRect(BackColor.GetHexColor(), CGlobalPosition.X*4, CGlobalPosition.Y, CSize.Width*4, CSize.Height, parent->bound/* Conflicting code */);
Draw->PRINTAT(ForeColor.GetHexColor(),CText, CGlobalPosition.X + nabs(CSize.Width - svlen(CText))/2,CGlobalPosition.Y + nabs(CSize.Height-16)/2, bound);
}
};
All help is welcomed. Thanks.
I have a class that has 2 bools and an array of pointers which I allocate on heap.The problem is when it calls the destructor it gives me an error,probably because it deletes too much,I saw it trying to access 0xdddddd and showing me this "Exception thrown: read access violation.
this was 0xDEEEDEEF."
1.How do I use "delete" better,is it because of the operator overload?
2.Also it says that i didn't initialized "QuadTree::childs",why?
class QuadTree {
public:
QuadTree* childs[4];
bool info;
bool parent;
QuadTree() {
for (int i = 0; i < 4; ++i) {
childs[i]=NULL;
}
info = false;
parent = false;
}
~QuadTree() {
for (int i = 0; i < 4; ++i) {
delete childs[i];
}
}
QuadTree& operator=(const QuadTree& tree) {
for (int i = 0; i < 4; ++i) {
childs[i] = new QuadTree;
if (tree.childs[i]->parent == 1) {
childs[i] = tree.childs[i];
}
childs[i]->info = tree.childs[i]->info;
childs[i]->parent = tree.childs[i]->parent;
}
return *this;
}
}
So this is the code for adding two trees.I created the overload operator for the next reason,if the node of one tree is white and the other is a parent,i just want to copy the parent.
void addTrees(const QuadTree& tree1, const QuadTree& tree2, QuadTree& end) {
if (tree1.info == 1 || tree2.info == 1) {
end.info = 1;
return;
}
else if (tree1.parent == 1 && tree2.parent == 1) {
end.parent = 1;
for (int i = 0; i < 4; ++i) {
end.childs[i] = new QuadTree;
addTrees(*tree1.childs[i], *tree2.childs[i], *end.childs[i]);
}
}
else if (tree1.parent == 1) {
end.parent = 1;
end = tree1;
}
else if (tree2.parent == 1) {
end.parent = 1;
end = tree2;
}
else {
end.info = 0;
}
}
The line childs[i] = tree.childs[i]; is not doing what you think it is doing.
You are now referencing the memory that they allocated and no longer referencing the memory that you allocated. Whoever tries to delete this memory second will have a bad time.
If you want to copy their child into your recently allocated child you will need to dereference the pointer to operate on the object itself. *childs[i] = *tree.childs[i]
The problem is in your assigmnent operator.
QuadTree& operator=(const QuadTree& tree) {
for (int i = 0; i < 4; ++i) {
childs[i] = new QuadTree;
if (tree.childs[i]->parent == 1) {
childs[i] = tree.childs[i];
}
childs[i]->info = tree.childs[i]->info;
childs[i]->parent = tree.childs[i]->parent;
}
return *this;
}
};
In these lines:
if (tree.childs[i]->parent == 1) {
childs[i]->info = tree.childs[i]->info;
childs[i]->parent = tree.childs[i]->parent;
childs[i] maybe a nullptr which is ok for assignment but not ok for dereferencing.
And with ->parent you do derefence a nullptr
Please check for nullptr before derefencing.
Basically i cant make work this logic simulator! I made an adjacency list that connects all the gates one to each other and then assign a value to them and AdjList that is the head should calculate the value using the function pointer. Problem is the only function it calls is And!(Xor Nand etc.. are never called)
The specific points are where pointer are initialized
struct AdjList
{
struct AdjListNode *head;
string GateName;
string OutputName;
bool result;
function <bool (vector <bool>)> ptrf;
};
and were they are assigned
if(i < Gate_IO.size() )
{
ptrPos = Gate_IO[i].find_first_of(' ');
switch (strtoi ( (Gate_IO[i].substr(0,ptrPos).c_str() )))
{
case strtoi("AND"):
{
VectorHeadPtr[i].ptrf = And;
break;
}
case strtoi("NAND"):
{
VectorHeadPtr[i].ptrf = Nand;
break;
}
case strtoi("OR"):
{
VectorHeadPtr[i].ptrf = Or;
break;
}
case strtoi("NOR"):
{
VectorHeadPtr[i].ptrf = Nor;
break;
}
case strtoi("XOR"):
{
VectorHeadPtr[i].ptrf = Xor;
break;
}
default:
break;
}
Then in function CalcGateValue() they are called to execute the program! it seems like they are recognised and assigned to the right value in VectorHeadPtr[i].ptrf i tried to cout in that point and it goes into that cycle but the only function called when i call CalcGateValue() is And! Am I missing something?
Here is the complete code:
#include <iostream>
#include <cstdlib>
#include <string>
#include <sstream>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
int compare(string a, string b)
{
int n = count(a.begin(), a.end(), 'I');
int q = count(b.begin(), b.end(), 'I');
return n > q;
}
constexpr unsigned int strtoi(const char* str, int h = 0) //string to int for switch cycle
{
return !str[h] ? 5381:(strtoi(str, h+1)*33)^str[h];
}
bool Xor(vector<bool> inputs)
{ cout<<"Xor function called!"<<endl;
int counter = 0;
for (unsigned int i = 0;i < inputs.size(); i++)
{
if (inputs.at(i) == 1)
{
counter++;
}
}
if (counter % 2) //Xor gate gives output 1 if and odd number of 1 inputs is given
{
return 1;
}
else
{
return 0;
}
}
bool And(vector<bool> inputs) //static per richiamare la funzione dalla classe
{ cout<<"And function called!"<<endl;
for (int i = 0; i < (inputs.size()-1); i++)
{
if(inputs.at(i) == 0)
{
return 0;
}
}
return 1;
}
bool Nand(vector<bool> inputs)
{ cout<<"Nand function called!"<<endl;
return !And(inputs);
}
bool Or(vector<bool> inputs)
{cout<<"Or function called!"<<endl;
for (int i = 0; i < (inputs.size()-1); i++)
{
if (inputs.at(i) != inputs.at(i+1) )
{
return 1;
}
}
return inputs.at(0);//Any position it's ok because all nPoss are the same.
}
bool Nor(vector<bool> inputs)
{ cout<<"Nor function called!"<<endl;
return !Or(inputs);
}
/*
* Adjacency list node
*/
struct AdjListNode
{
int nPos;
bool gValue;
string name;
struct AdjListNode* next;
};
/*
* Adjacency list
*/
struct AdjList
{
struct AdjListNode *head;
string GateName;
string OutputName;
bool result;
function <bool (vector <bool>)> ptrf;
};
/**
* Class Graph
*/
class Graph
{
private:
int V;
int circInputs = 3;
int circOutputs = 2;
int circGates;
int PrimaryInputs = 0;
vector<string> ioPuts;
struct AdjList* VectorHeadPtr;
public:
Graph(vector<string> Gate_IO)
{
int ptrPos,cntr;
int cntrIO = 0;
int prevPrimaryInputs = 0;
bool flag_remove_duplicates = 0;
string GateToConnect;
circGates = Gate_IO.size();
V=Gate_IO.size() + circInputs + circOutputs; //nĀ°gates+input+output letti dal file
sort (Gate_IO.begin(), Gate_IO.end(), compare);
for (cntr = 0; cntr < (Gate_IO.size()-1) && (PrimaryInputs == prevPrimaryInputs); cntr++)
{
PrimaryInputs = count (Gate_IO[cntr+1].begin(), Gate_IO[cntr+1].end(), 'I');
prevPrimaryInputs = count (Gate_IO[cntr].begin(), Gate_IO[cntr].end(), 'I');
}
PrimaryInputs = cntr; //Here starts first N
for (int i = 0;i<Gate_IO.size();i++)
VectorHeadPtr = new AdjList [V];
for (int i = 0; i < V; i++)
{
if(i < Gate_IO.size() )
{
ptrPos = Gate_IO[i].find_first_of(' ');
switch (strtoi ( (Gate_IO[i].substr(0,ptrPos).c_str() )))
{
case strtoi("AND"):
{
VectorHeadPtr[i].ptrf = And;
break;
}
case strtoi("NAND"):
{
VectorHeadPtr[i].ptrf = Nand;
break;
}
case strtoi("OR"):
{
VectorHeadPtr[i].ptrf = Or;
break;
}
case strtoi("NOR"):
{
VectorHeadPtr[i].ptrf = Nor;
break;
}
case strtoi("XOR"):
{
VectorHeadPtr[i].ptrf = Xor;
break;
}
default:
break;
}
VectorHeadPtr[i].head = NULL;
stringstream ss;
ss << Gate_IO[i];
for (string temp; ss >> temp;)
{
if ( (temp.at(0)=='I') || (temp.at(0)=='O') && (temp!="OR") )
{
ioPuts.push_back(temp);
}
else if (temp.at(0) == 'U')
{
VectorHeadPtr[i].GateName=temp;
}
}
ptrPos = Gate_IO[i].find_last_of(' ');
VectorHeadPtr[i].OutputName = Gate_IO[i].substr(ptrPos);
}
else
{
if (flag_remove_duplicates == 0)
{
sort (ioPuts.begin(), ioPuts.end() );
ioPuts.erase (unique (ioPuts.begin(), ioPuts.end() ), ioPuts.end() );
flag_remove_duplicates = 1;
}
VectorHeadPtr[i].head = NULL;
VectorHeadPtr[i].ptrf = NULL;
VectorHeadPtr[i].GateName = ioPuts[cntrIO];
cntrIO++;
}
}
for (int i = 0; i < Gate_IO.size(); i++)
{
for(int j = 0; j < 2; j++)
{
ptrPos = Gate_IO[i].find_first_of(' ')+1;
Gate_IO[i].erase (0,ptrPos);
}
ptrPos = Gate_IO[i].find_last_of(' ')+1;
Gate_IO[i].erase( ptrPos);
stringstream ss;
ss << Gate_IO[i];
ss >> GateToConnect;
for (string temp; ss >> temp;)
{
addEdge(GateToConnect,temp);
}
}
}
/**
* Creates new adjacency list node for addEdge function
*/
AdjListNode* newAdjListNode(int nPos, string Name)
{
AdjListNode* newNode = new AdjListNode;
newNode->nPos = nPos;
newNode->name = Name;
newNode->next = NULL;
return newNode;
}
/**
* Add edge to graph
*/
void addEdge(string source, string destination)
{
int from, to;
for (int i = 0; i < V; ++i)
{
if ( (source == VectorHeadPtr[i].GateName) || (source == VectorHeadPtr[i].OutputName) )
{
from = i;
}
else if (( destination == VectorHeadPtr[i].GateName) || (destination == VectorHeadPtr[i].OutputName) )
{
to = i;
}
}
AdjListNode* newNode = newAdjListNode(to, destination);
newNode->next = VectorHeadPtr[from].head;
VectorHeadPtr[from].head = newNode;
}
/*
* Print the graph
*/
void printGraph()
{
for (int i = 0; i < circGates; i++)//meno ooutput+input
{
AdjListNode* Ptr = VectorHeadPtr[i].head;
cout<<endl<<"Gate connections for "<<VectorHeadPtr[i].GateName;
while (Ptr)
{
cout <<"-> "<< Ptr->name;
Ptr = Ptr->next;
}
cout<<" Output name is:"<<VectorHeadPtr[i].OutputName<<endl;
}
}
void calcGateVal()
{
vector<bool> Val={0, 1, 0};
vector<bool> Op;
for (int i = 0; i < circOutputs; i++)
{
ioPuts.pop_back();
}
for (int i = 0; i < circGates; i++)
{
AdjListNode* Ptr = VectorHeadPtr[i].head;
while (Ptr)
{
if (Ptr->name.at(0) == 'I')
{
for (int j = 0; j < ioPuts.size(); j++)
{
if (Ptr->name == ioPuts[j])
{
Ptr->gValue = Val[j];
}
}
}
Ptr = Ptr->next;
}
}
for (int i = 0; i < PrimaryInputs; i++)
{
AdjListNode* Ptr = VectorHeadPtr[i].head;
while (Ptr)
{
Op.push_back(Ptr->gValue);
Ptr = Ptr->next;
}
VectorHeadPtr[i].result = VectorHeadPtr[i].ptrf(Op);
cout<<"Gate Value is: "<<VectorHeadPtr[i].result<<" OutputName: "<<VectorHeadPtr[i].OutputName<<" GateName: "<<VectorHeadPtr[i].GateName<<endl;
Op.clear();
}
for (int i = PrimaryInputs; i < V; i++)
{
AdjListNode* Ptr = VectorHeadPtr[i].head;
while (Ptr)
{
for (int j = 0; j < PrimaryInputs; j++)
{
if (Ptr->name == VectorHeadPtr[j].OutputName)
{
Ptr->gValue = VectorHeadPtr[j].result;
}
}
Ptr = Ptr->next;
}
}
for (int i = PrimaryInputs; i < circGates; i++)
{
AdjListNode* Ptr = VectorHeadPtr[i].head;
while (Ptr)
{
Op.push_back(Ptr->gValue);
Ptr = Ptr->next;
}
VectorHeadPtr[i].result = VectorHeadPtr->ptrf(Op);
Op.clear();
}
}
void displayOutput()
{ cout<<endl;
for (int i = 0; i < circGates; i++)
{
cout<<"Value of outputs are ("<<VectorHeadPtr[i].GateName<<") "<<VectorHeadPtr[i].OutputName<<": "<<VectorHeadPtr[i].result<<endl;
}
}
};
/*
* Main
*/
int main()
{
vector<string> G_d;
G_d.push_back("AND 2 U0 I0 I1 N0");
G_d.push_back("XOR 2 U1 N0 I2 O0");
G_d.push_back("AND 2 U2 N0 I2 N1");
G_d.push_back("AND 2 U3 I0 I1 N2");
G_d.push_back("OR 2 U4 N1 N2 O1");
Graph gh(G_d);
gh.calcGateVal();
gh.displayOutput();
gh.printGraph();
// print the adjacency list representation of the above graph
return 0;
}
I think your code does not produce what you say it produces. Please see here:
http://coliru.stacked-crooked.com/a/405b04c8d9113790 - Check the output of this
Why do you want to convert strings to integers with strtoi with your case comparisons? :
case strtoi("NAND"):
a better approach would be strcmp or store each in a string perhaps a look up table and do a "==" equal equal comparison which is overloaded for strings.
Consider passing your vectors and objects around by reference rather than value, you might be expecting a return in your object but since you pass by value you never see them and this also avoids the overhead of making a copy of the vectors.
I have to develop two functions. One is an application level function that merges two sortedlists implemented using dynamic arrays. The other is the same except its supposed to be a member function. I get invalid allocation size. When I trace the function it successfully returns without an error buy as soon as I reach the original calling code I get the error. Here is the code for both functions.
Application level function:
ArraySortedType& merge(const ArraySortedType& list1, const ArraySortedType& list2)
{
ItemType temp;
ArraySortedType ret, list1Copy=list1, list2Copy=list2;
list1Copy.ResetList();
while (list1Copy.GetNextItem(temp) == Success)
ret.InsertItem(temp);
list2Copy.ResetList();
while (list2Copy.GetNextItem(temp) == Success)
ret.InsertItem(temp);
return ret;
}
Member function:
ArraySortedType& ArraySortedType::merge(const ArraySortedType& list)
{
ArraySortedType s, copy = list;
ItemType temp;
copy.ResetList();
while (copy.GetNextItem(temp) == Success)
s.InsertItem(temp);
for (int k = 0; k < length; k++)
s.InsertItem(info[k]);
return s;
}
Code where I call functions:
ArraySortedType u = merge(s, n);
//ArraySortedType k = merge(s, n);
cout << "Length of u is: " << u.LengthIs() << endl;
// cout << "Length of k is: " << k.LengthIs() << endl;
Even the commented out code doesn't work.
Also there is alot of code for implementing the ArraySortedType that I've left out because I think it's unnecessary. Most of it was already given with the lab. InsertItem was implemented by me and is used quite a bit so I'll include it here:
Error_Code ArraySortedType::InsertItem ( ItemType item)
{
if(!length)
{
info[0] = item;
length++;
return Success;
}
for(int i=0;i<=length;i++)
{
if(info[i].ComparedTo(item) != LESS || i==length)
{
for(int j=length;j>i;j--)
info[j] = info[j-1];
info[i]=item;
length++;
return Success;
}
}
return Fail;
}
GetNextItem() and ResetList() were already given so they cant be the problem so I'll leave them out but just tell me if they are required.
I've traced both of them and googled quite a bit but this problem has left me scratching my head. Any help would be appreciated.
EDIT:
I guess the implementation of ArraySortedList will be necessary. Here it is. Guess I don't really expect anyone to actually go through it though:
//ArraySortedType.cpp
#include "ArraySortedType.h"
ArraySortedType::ArraySortedType (int max_items)
{
length =0;
MAX_ITEMS = max_items;
currentPos =-1;
try
{
info = new ItemType[MAX_ITEMS];
}
catch(std::bad_alloc exception)
{
//Severe problem, do not keep program running
cout <<"Memory full "<< endl;
exit(1);
}
}
ArraySortedType::~ArraySortedType()
{
delete [] info;
info = NULL;
}
void ArraySortedType::ResetList ( )
{
currentPos = -1;
}
bool ArraySortedType::IsFull ( ) const
{
if(length == MAX_ITEMS)
{
try
{//Check if memory allocation is fine
ItemType * temp = new ItemType[2*MAX_ITEMS];
delete [] temp;
return false;
}
catch(std::bad_alloc exception)
{
return true;
}
}
return false;
}
bool ArraySortedType::IsEmpty () const {
return (length==0);
}
int ArraySortedType:: LengthIs () const {
return length;
}
Error_Code ArraySortedType::DeleteItem ( ItemType item ) {
int location = 0;
while ((item.ComparedTo(info[location]) != EQUAL ) && location < length)
location++;
if (location == length) return Fail;
info[location] = info[length - 1];
length--;
return Success;
}
Error_Code ArraySortedType::GetNextItem (ItemType& item) {
currentPos++;
if( currentPos == length ) return Fail;
item = info[currentPos] ;
return Success;
}
ArraySortedType::ArraySortedType(const ArraySortedType & ust)
{
MAX_ITEMS =ust.MAX_ITEMS;
length=ust.length;
try
{
info = new ItemType[MAX_ITEMS];
}
catch(std::bad_alloc exception)
{
//Severe problem, do not keep program running
cout <<"Memory full "<< endl;
exit(1);
}
for(int i=0;i<length; i++)
info[i] = ust.info[i];
currentPos=ust.currentPos;
}
ArraySortedType& ArraySortedType::operator=(const ArraySortedType & ust)
{
if(this == &ust) return *this;
if(MAX_ITEMS !=ust.MAX_ITEMS)
{
delete [] info;
MAX_ITEMS = ust.MAX_ITEMS;
try
{
info = new ItemType[MAX_ITEMS];
}
catch(std::bad_alloc exception)
{
//Severe problem, do not keep program running
cout <<"Memory full "<< endl;
exit(1);
}
}
currentPos=ust.currentPos;
length=ust.length;
for(int i=0;i<length; i++)
info[i] = ust.info[i];
return *this;
}
//Assumes that an employee has unique ID
bool ArraySortedType::operator==(const ArraySortedType & ust)
{
if(this == &ust) return true;
if(length!=ust.length) return false;
if(currentPos!=ust.currentPos) return false;
for(int i=0;i<length; i++)
if(info[i].ComparedTo(ust.info[i])!=EQUAL) return false;
return true;
}
Error_Code ArraySortedType::InsertItem ( ItemType item)
{
if(!length)
{
info[0] = item;
length++;
return Success;
}
for(int i=0;i<=length;i++)
{
if(info[i].ComparedTo(item) != LESS || i==length)
{
for(int j=length;j>i;j--)
info[j] = info[j-1];
info[i]=item;
length++;
return Success;
}
}
return Fail;
}
Error_Code ArraySortedType::RetrieveItem (ItemType& item , bool& found)
{
found = false;
int front = 0, back = length - 1, midpoint=(length-1)/2;
while (front<=back)
{
switch (info[midpoint].ComparedTo(item))
{
case EQUAL:
item = info[midpoint];
found = true;
break;
case LESS:
front = midpoint + 1;
break;
case GREATER:
back = midpoint - 1;
break;
}
if (found)
break;
midpoint = ((back - front) / 2 + front);
}
return Fail;
}
Error_Code ArraySortedType::Delete(ItemType startKey, ItemType endKey)
{
bool startFound = false, endFound = false;
int numberDeleted=0, startLocation;
bool deleting = false;
for (int i = 0; i < length; i++)
{
if (info[i].ComparedTo(startKey) == EQUAL)
{
startLocation = i;
deleting = true;
startFound = true;
}
if (deleting)
numberDeleted++;
if (info[i].ComparedTo(endKey) == EQUAL)
{
deleting = false;
endFound = true;
}
}
if (!(startFound || endFound))
return Fail;
length -= numberDeleted;
for (int i = startLocation; i < length; i++)
info[i] = info[i + startLocation];
return Success;
}
ArraySortedType ArraySortedType::RetrieveItemsInRange(ItemType startKey, ItemType endKey)
{
ArraySortedType r;
bool startFound = false, endFound = false;
int numberDeleted = 0, startLocation;
bool retrieving = false;
for (int i = 0; i < length; i++)
{
if (info[i].ComparedTo(startKey) == EQUAL)
{
startLocation = i;
retrieving = true;
startFound = true;
}
if (retrieving)
r.InsertItem(info[i]);
if (info[i].ComparedTo(endKey) == EQUAL)
{
retrieving = false;
endFound = true;
}
}
return r;
}
ArraySortedType& ArraySortedType::merge(const ArraySortedType& list)
{
ArraySortedType s, copy = list;
ItemType temp;
copy.ResetList();
while (copy.GetNextItem(temp) == Success)
s.InsertItem(temp);
for (int k = 0; k < length; k++)
s.InsertItem(info[k]);
return s;
}
ItemType is defined as a class Employee. I really hope I don't have to include it here as well. The class Employee has a compareTo class defined as follows:
RelationType Employee::ComparedTo(const Employee & e)
{
if(eid < e.eid) return LESS;
else if(eid == e.eid) return EQUAL;
else return GREATER;
}
There is a an enum called relation type that has values LESS, EQUAL and GREATER.
I know that similar question has been asked,but I still can not figure out what is wrong.As mentioned above,I am debugging a program with VS2010 which always telling me "This may be due to a corruption of the heap, which indicates a bug in SwiftIndex.exe or any of the DLLs it has loaded...".So,here is part of my code:
Status PrefixQuickSI::my_QucikSI(std::vector<_QISymbol> &cur_sequence, QISequence graphcode, int depth, int feature_size, ECVector<char> cur_UsageTab, ECVector<SequenceIndex> cur_MappingTab, bool &flag)
{
Status st;
int vcnt = m_QueryGraph->V();
_QISymbol T;
if(depth == 0)
{
T.tSymbol = graphcode.sequence[depth]->tSymbol;
T.rSymbols.clear();
for(int i = 0; i < graphcode.sequence[depth]->numOfRSymbol; i++)
{
int v1,v2;
Label elabel;
v1 = graphcode.sequence[depth]->rSymbol[i].val;
v2 = graphcode.sequence[depth]->rSymbol[i+1].val;
elabel = graphcode.sequence[depth]->rSymbol[i].lable;
if(m_QueryGraph->getELabel(cur_MappingTab[v1],cur_MappingTab[v2]) != elabel)
{
flag = false;
return OK;
}
T.rSymbols.push_back(graphcode.sequence[depth]->rSymbol[i]);
T.rSymbols.push_back(graphcode.sequence[depth]->rSymbol[i+1]);
i++;
}
depth++;
cur_sequence.push_back(T);
if(depth == graphcode.numOfPrefixNode)
{
flag =true;
return OK;
}
else
{
st = my_QucikSI(cur_sequence, graphcode,depth, feature_size, cur_UsageTab, cur_MappingTab, flag);
if(flag == true)
{
return OK;
}
else
{
flag = false;
return OK;
}
}
}
else
{
T.tSymbol = graphcode.sequence[depth]->tSymbol;
for( int j = 0; j < graphcode.sequence[depth]->numOfRSymbol; ++j )
{
RSymbol rSymbol;
rSymbol = graphcode.sequence[depth]->rSymbol[j];
T.rSymbols.push_back(rSymbol);
}
int pV;
VertexIDSet Vcandiates;
for( int i = 0; i < vcnt; i++ )
{
pV = T.tSymbol.p;
if( cur_UsageTab[i] > 0 || m_QueryGraph->getLabel(i) != T.tSymbol.l || m_QueryGraph->getELabel(i, cur_MappingTab[pV]) != T.tSymbol.pl)
continue;
Vcandiates.insert(i);
}
for( VertexIDSet::const_iterator v = Vcandiates.begin(); v != Vcandiates.end(); v++ )
{
bool mis_match = false;
for( std::vector<RSymbol>::const_iterator r = T.rSymbols.begin(); r != T.rSymbols.end(); r++ )
{
if( !MatchREntry(cur_sequence, *v, *r) )
{
mis_match = true;
break;
}
}
if( mis_match )
continue;
cur_MappingTab[feature_size + depth] = *v;
cur_UsageTab[*v] = 1;
depth++;
cur_sequence.push_back(T);
if(depth == graphcode.numOfPrefixNode)
{
flag = true;
return OK;
}
else
{
st = my_QucikSI(cur_sequence, graphcode,depth, feature_size, cur_UsageTab, cur_MappingTab,flag);
if(flag == true)
{
return OK;
}
else
{
cur_UsageTab[*v] = 0;
depth--;
}
}
}
}
return OK;
}
and the calling function statement is:
int depth = 0;
st = my_QucikSI(cur_sequence, datacodes[cur_graphid], depth, cur_size,cur_UsageTab,cur_MappingTab, flag);
I have debugged step by step,and found that the "heap corruption" occurred in the second return of the recursion of function my_QuickSI(flag already equaled true at the third recursion and function returned to the second recursion,when it's about to return to the first recursion,the "heap corruption" happened).
Hope someone find where the problem is.
You can find my previous answer useful for your problem:
https://stackoverflow.com/a/22074401/2724703
In general heap corruption is often detected after the real corruption has already occurred by some DLL/module loaded within your process.