Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
i have a problem with this codes. this program designed to use depth-first search in c++. i compiled it with Dev-Cpp , TurboC++ and visual studio .it compiled and the exe file have been made. but it make segment fault during execute. where is problem and what should i do ?
#include <stdio.h>
#include <string.h>
#include <iostream.h>
#include <vector.h>
#include <deque.h>
using namespace std;
//Structure for Adding Edge to Graph
struct Neighbor
{
string Name;
int Distance;
int ShortestDistance;
};
//Class Data Structure for City type Node:
class City
{
public:
string Name;
City( );
City(string);
vector<Neighbor> Neighbors;
vector<Neighbor>::iterator NeighborNumber;
void AddNeighbor (string, int);
};
//Parameterless Class constructor
City::City( )
{
Name="";
NeighborNumber=Neighbors.begin( );
}
//Class Constructor with Name supplied:
City::City(string CityName)
{
Name=CityName;
NeighborNumber=Neighbors.begin( );
}
//Function or Method to Add Connected Node to City data structure
void City::AddNeighbor(string NeighborName, int NeighborDistance)
{
Neighbor TempNeighbor;
TempNeighbor.Name=NeighborName;
TempNeighbor.Distance=NeighborDistance;
Neighbors.push_back(TempNeighbor);
NeighborNumber=Neighbors.begin( );
}
//Data Structure for Entire Map
vector<City> Cities;
void MakeMap()
{
City TempCity;
//Enter data for Arad
TempCity.Name="Arad";
TempCity.Neighbors.clear();
TempCity.AddNeighbor("Zerind",75);
TempCity.AddNeighbor("Sibiu", 140);
TempCity.AddNeighbor("Timisoara",118);
Cities.push_back(TempCity);
//Enter data for Bucharest
TempCity.Name="Bucharest";
TempCity.Neighbors.clear();
TempCity.AddNeighbor("Giurgiu",90);
TempCity.AddNeighbor("Urziceni",85);
TempCity.AddNeighbor("Fagaras",211);
TempCity.AddNeighbor("Pitesti",101);
Cities.push_back(TempCity);
}
//Function to Display contents of Cities data structure to screen:
void PrintCities()
{
City TempCity;
Neighbor TempNeighbor;
vector<City>::iterator CityNumber;
//Loop Through Entire Cities vector
for(CityNumber=Cities.begin();CityNumber<Cities.end();CityNumber++)
{
TempCity=*CityNumber;
cout<<"Current City: "<<TempCity.Name<<endl;
cout<<"Neighbors: ";
//Loop Through Each Neighbor printing name and distance
for(TempCity.NeighborNumber=TempCity.Neighbors.begin();
TempCity.NeighborNumber<TempCity.Neighbors.end();
TempCity.NeighborNumber++)
{
TempNeighbor=*TempCity.NeighborNumber;
cout<<" "<<TempNeighbor.Name;
cout<<","<<TempNeighbor.Distance;
}
cout<<endl<<endl;
}
}
//Function to return Success or Failure on finding the Child Node given the
//Parent is a structure of type Neighbor. The ChildCity is returned by reference.
bool GetChildCity(Neighbor Parent, City* ChildCity)
{
City TempCity;
vector<City>::iterator CityNumber;
for(CityNumber=Cities.begin();CityNumber<Cities.end();CityNumber++)
{
TempCity=*CityNumber;
if(TempCity.Name==Parent.Name)
{
*ChildCity=TempCity;
return true;
}
}
return false;
}
class PathRecord
{
public:
string AccumulatedPath;
string LastEntry;
int AccumulatedDistance;
PathRecord(string);
void AddPath(PathRecord, City, Neighbor);
};
PathRecord::PathRecord(string Start)
{
AccumulatedPath=Start;
LastEntry=Start;
AccumulatedDistance=0;
}
void PathRecord::AddPath(PathRecord ParentRecord, City ChildCity, Neighbor CurrentNeighbor)
{
this->AccumulatedPath=ParentRecord.AccumulatedPath+" - "+ChildCity.Name;
this->LastEntry=ChildCity.Name;
this->AccumulatedDistance=ParentRecord.AccumulatedDistance+CurrentNeighbor.Distance;
}
vector<PathRecord> PathsTraveled;
//Perform Depth First Search giving Start Location and Ending Location
bool DepthFirstSearch(string StartName, string EndName)
{
City CurrentCity;
City StartCity;
City ChildCity;
City ExploredCity;
City FrontierCity;
Neighbor CurrentNeighbor;
bool StartCityFound=false;
bool GoalFound=false;
bool AlreadyExplored;
bool AlreadyInFrontier;
bool NewChildFound;
bool PathFound;
vector<City>::iterator CityNumber;
deque<City> Frontier;
deque<City> Explored;
deque<City>::iterator FrontierCityNumber;
deque<City>::iterator ExploredCityNumber;
PathRecord NewRecord(StartName);
PathRecord TemporaryRecord("");
vector<PathRecord>::iterator PathNumber;
if(StartName==EndName) return true;
if(StartName=="" || EndName == "") return false;
//*************************************************************************
// Search For Start
//*************************************************************************
for(CityNumber=Cities.begin();CityNumber<Cities.end();CityNumber++)
{
CurrentCity=*CityNumber;
if(CurrentCity.Name==StartName)
{
StartCity=CurrentCity;
StartCityFound=true;
}
}
if(StartCityFound==false) return false;
PathsTraveled.push_back(NewRecord);
Frontier.push_back(StartCity);
//*************************************************************************
// Search For Goal
//*************************************************************************
cout<<"\nRecording Exploratory Process:\n"<<"Start Location: "<<
StartName<<"\t Ending Location: "<<EndName<<endl;
//Get Next Location in the Frontier
while(!Frontier.empty() && GoalFound==false)
{
CurrentCity=Frontier.back();
cout<<"\nCurrent City: "<<CurrentCity.Name<<endl;
NewChildFound=false;
//Look through the Neighbors until an explored City is found.
while(CurrentCity.NeighborNumber<CurrentCity.Neighbors.end() && NewChildFound==false)
{
CurrentNeighbor=*CurrentCity.NeighborNumber;
cout<<"Current Neighbor: "<<CurrentNeighbor.Name<<endl;
if(GetChildCity(CurrentNeighbor, &ChildCity)==false)
{
cout<<"Didn't find a child\n";
return false;
}
if(ChildCity.Name==EndName)
{
cout<<"Goal Found\n";
GoalFound=true;
}
//Check for Child Already Explored
AlreadyExplored=false;
ExploredCityNumber=Explored.begin();
while(AlreadyExplored==false && ExploredCityNumber<Explored.end())
{
ExploredCity=*ExploredCityNumber;
if(ExploredCity.Name==ChildCity.Name) AlreadyExplored=true;
ExploredCityNumber++;
}
//Check for Child Already in Frontier
if(AlreadyExplored==false)
{
AlreadyInFrontier=false;
FrontierCityNumber=Frontier.begin();
while(AlreadyInFrontier==false && FrontierCityNumber<Frontier.end())
{
FrontierCity=*FrontierCityNumber;
if(FrontierCity.Name==ChildCity.Name) AlreadyInFrontier=true;
FrontierCityNumber++;
}
}
//Put the parent in the Frontier queue and Expand the Child Node
//Record the process in the Paths Traveled vector.
if(AlreadyExplored==false && AlreadyInFrontier==false)
{
Frontier.push_back(ChildCity);
NewChildFound=true;
PathNumber=PathsTraveled.begin( );
PathFound=false;
while(PathFound==false && PathNumber<PathsTraveled.end( ))
{
TemporaryRecord=*PathNumber;
if(TemporaryRecord.LastEntry==CurrentCity.Name)
{
NewRecord.AddPath(TemporaryRecord,
ChildCity, CurrentNeighbor);
PathsTraveled.push_back(NewRecord);
PathFound=true;
}
PathNumber++;
}
}
CurrentCity.NeighborNumber++;
}
//Display the Explored Queue on each pass
if(NewChildFound==false)
{
Explored.push_back(CurrentCity);
Frontier.pop_back();
}
cout<<"Explored: ";
for(ExploredCityNumber=Explored.begin();
ExploredCityNumber<Explored.end();ExploredCityNumber++)
{
ExploredCity=*ExploredCityNumber;
cout<<ExploredCity.Name<<" \t";
}
cout<<endl;
//Display the Frontier Queue on each pass
cout<<"Frontier: ";
for(FrontierCityNumber=Frontier.begin();
FrontierCityNumber<Frontier.end();FrontierCityNumber++)
{
FrontierCity=*FrontierCityNumber;
cout<<FrontierCity.Name<<" \t";
}
cout<<endl;
}
return GoalFound;
}
//Goal Path will print the path used to locate the Goal
//Supply the name of the goal after a search has been successful
void PrintGoalPath(string GoalName)
{
vector<PathRecord>::iterator PathNumber;
PathRecord TemporaryRecord("");
cout<<"\nGoal Path: "<<endl;
for(PathNumber=PathsTraveled.begin();PathNumber<PathsTraveled.end();PathNumber++)
{
TemporaryRecord=*PathNumber;
if(TemporaryRecord.LastEntry==GoalName)
cout<<TemporaryRecord.AccumulatedPath
<<" "<<TemporaryRecord.AccumulatedDistance<<endl;
}
cout<<endl;
}
//Program Starts here:
int main()
{
bool GoalFound;
MakeMap();
string StartLocation="Arad";
string GoalState="Bucharest";
GoalFound=DepthFirstSearch(StartLocation, GoalState);
if(GoalFound) PrintGoalPath(GoalState);
else cout<<"Couldn't Do It - "<<GoalState<<" is nowhere to be found!!\n";
return 0;
}
Segment Fault means you have tried to access memory beyond the boundary of segment, maybe code or data segment.
The error is :
vector iterators incompatible
Why?
Because you have copied an Array from A to B, but you want to use A.begin() iterator to compare with B's iterator, and this will not pass compiler's compatibility check, in Visual Studio,
void _Compat(const _Myiter& _Right) const
{ // test for compatible iterator pair
if (this->_Getcont() == 0
|| this->_Getcont() != _Right._Getcont())
{ // report error
_DEBUG_ERROR("vector iterators incompatible");
_SCL_SECURE_INVALID_ARGUMENT;
}
}
So my advice is ,do not try to save the iterator that points to the vector begin, you can use a temporary iterator when need
And further advice, learn C++ systematically, do not write codes as you think unless you have enough confidence.
Come on, work hard, you can make it!
Related
In my C++ program (I know I should have header files and stuff but this is the teacher requested format) it has a compilation error no matching function call for enqueue and I've tried using . and -> operators as well. Screenshots and code below. I'd like to know why I'm getting that error and how to avoid it in the future.
#include <iostream>
#include <string>
using namespace std;
struct plane
{
string name;
char state;
//time
};
struct Queue // creation of queue for landing
{
int front, end, size;
unsigned capacity; // makes an integer var that cannot be negative
plane* planearray;// * and [] are synonymous
};
//Queue operator =(plane* array, const Queue& queue)
//{
//}
plane* createplane(char state, string name)
{
cout<<"Enter the plane's name";
cin>>name;
cout<<"Is the plane landing or taking off? 'T t (takeoff)' or 'L l(landing)' "<<endl;
cin>>state;
}
// function to create a queue of a given size
/*Why pointer in obj creation*/
Queue* createQueue(unsigned capacity) // takes in capacity because you want to modify it
{
char takeoffland;
cout<<"Is this a takeoff or landing queue? enter 'T t (takeoff)' or 'L l(landing)' "<<endl;
cin>>takeoffland;
if(takeoffland=='T'||takeoffland=='t')
{
Queue* tqueue = new Queue();
tqueue->capacity=capacity;
tqueue->front=tqueue->size = 0;
tqueue->end = capacity -1;
/*website has algorithm as [(queue->capactiy*sizeof(class)] looked up sizeof to be size of the data type but dont quite get it still */
tqueue->planearray = new plane[(tqueue->capacity)];
return tqueue;
}
else if(takeoffland=='L'||takeoffland=='l')
{
Queue* lqueue = new Queue();
lqueue->capacity=capacity;
lqueue->front=lqueue->size = 0;
lqueue->end = capacity -1;
/*website has algorithm as [(queue->capactiy*sizeof(class)] looked up sizeof to be size of the data type but dont quite get it still */
lqueue->planearray = new plane[(lqueue->capacity)];
return lqueue;
}
else{
cout<<"Invalid input try again";
}
}
bool isFull(Queue* queue)
{
if(queue->size == queue->capacity)
{
cout<<"The queue is full";
return true;
}
else{
return false;
}
}
bool isEmpty(Queue* queue)
{
if(queue->size == 0)
{
cout<<"The queue is empty";
return true;
}
else
{
return false;
}
}
void enqueue(Queue* queue, plane* p)
{
if(isFull(queue))
{
cout<<"Cannot add to queue, its full";
return;
}
plane* insert = p;
queue->end = queue->end+1;// makes end the very end
queue->planearray[queue->end] = *insert;// makes the end the new addition to queue
queue->size += 1;
if(p->state=='t'||p->state=='T')
{
cout<<"Plane added to takeoff queue"<<endl;
}
else if(p->state=='L'||p->state=='l')
{
cout<<"Plane added to landing queue"<<endl;
}
}
int main(){
Queue* landing = createQueue(1);
plane p1;
enqueue(landing, p1);
};
I am writing a graph implementation in c++ where the cities are vertices, flights from one city to another city represent an edge, and the weights are the distances between those cities. The vertices,edges, and weights are stored in a file and when the program runs it would load the vertices, edges, and weights into the program. I am using an adjacency matrix where it represents the edges.
Now when the program runs it will prompt the user to either:
Choose Departure city
Exit. Option two just terminates the program.
If the user chooses option one, then it will list all the cities from the file. There a seven cities I chose. So it will look like 1.)Los Angeles 2.) New York 3.) Miami and so on until option 7. When the user chooses an option it will then list all the destination cities except the departure city the user chose. There would be three possibilities once the user chooses his destination city.
Now the first possibility would be there would be no direct or through connection between city A and city B and the program will output, No destination between [departure city] and [destination city] , press any key to return. Once the user presses any key, the menu will display again. The Second possibility would be if there is a direct connection between the city then the program would output the direct connection between [departure city]-[destination city] = [miles] and the miles between the city, or if there isn't a direct connection it will say no direct connection and the user can go back to the menu.
The third possibility would be that there would be a through connection and it will show the departure city and destination city with all the cities between them and the total miles it covers between them and the user can press any key to return to the menu.
Now the problem I"m having is getting the info from the file, I can't figure out how to get the info from the file or how to write the file so the program knows which are the vertices,edges,and weights. Also, how to display the cities and which have the direct connection, through connection, or no connection at all.
include <iostream>
#include <fstream>
#pragma once
const int NULL_EDGE = 0;
typedef std::string String;
class GraphType
{
private:
int edges[50][50];
int m_numVertices;
int m_maxVertices;
int m_distance;
String* m_vertices;
bool* marks; // marks[i] is the mark for vertices[i]
int IndexIs(String*, String);
public:
GraphType();
~GraphType();
bool isEmpty() const;
bool isFull(); //to do
int GetWeight(String, String); // to do
void ClearMarks(); // to do
void MarkVertex(String) // to do
bool isMarked(String) // to do
void addVertex(String);
void addEdge(String, String, int);
void displayCities();
};
#include "GraphType.h"
GraphType::GraphType()
{
m_maxVertices = 50;
m_distance = 0;
m_vertices = new String[m_maxVertices];
marks = new bool[50];
std::ifstream loadFile;
loadFile.open("load.txt");
if (loadFile.fail())
std::cout << " Error opening load.txt\n";
else
{
//stuck here
}
loadFile.close();
}
GraphType::~GraphType()
{
delete[] m_vertices;
delete[] marks;
}
int GraphType::IndexIs(String* vertices, String vertex)
{
int index = 0;
while (!(vertex == m_vertices[index]) == 0)
index++;
return index;
}
void GraphType::addVertex(String vertex)
{
m_vertices[m_numVertices] = vertex;
for (int i = 0; i < m_numVertices; i++)
{
edges[m_numVertices][i] = NULL_EDGE;
edges[i][m_numVertices] = NULL_EDGE;
}
m_numVertices++;
}
void GraphType::addEdge(String startVertex, String destVertex, int weight)
{
int row;
int col;
row = IndexIs(m_vertices, startVertex);
col = IndexIs(m_vertices, destVertex);
edges[row][col] = weight;
}
void GraphType::displayCities()
{
//stuck here
}
bool GraphType::isEmpty() const
{
return (m_numVertices == 0);
}
#include "GraphType.h"
int FlyMenu();
void CitiesMenu(GraphType&);
int main()
{
int choose;
GraphType gt;
do
{
choose = FlyMenu();
switch (choose)
{
case 1: CitiesMenu(gt);
break;
case 2:
break;
default: std::cout << " Invalid Input\n";
break;
}
} while (choose != 2);
return 0;
}
int FlyMenu()
{
int option;
std::cout << " 1.) Choose Depature City\n";
std::cout << " 2.) Exit\n";
std::cout << " Enter option: ";
std::cin >> option;
return option;
}
void CitiesMenu(GraphType& gt)
{
gt.displayCities();
}
I know about the depth Traversal and breadth Traversal algorithms to see if there is a connection between a city or not, but I don't know how to implement them for this scenario. I can't use the Standard Template Library, only std::vector. I was thinking about writing another class, but I don't know what what that class will help me with.
From what I got you have two questions:
read / write from file: the simplest solution would be freopen.
freopen("input","r",stdin)
freopen("output","w",stdout)
now every cin & cout operation will be done on the files you defined on freopen
implementing DFS / BFS: I will code the simplest type of DFS for you and you have to edit it to suite you program.
bool visit[MAX_CITY + 10];
void DFS(int x){
visit[x] = 1;
for (int i=1;i<=MAX_CITY;i++){
int nx = i;
if (adj[x][i] == -1) continue; // a cost of -1 means no flight
if (visit[nx]) continue;
DFS(nx);
}
}
I was trying to implementing dfs to print paths from starting node . I followed algorithm from Coremen 's book . Here is my code :
DFS
#include<iostream>
#include<stack>
using namespace std;
int vertex,edge,source,time,adjacency_matrix[100][100],parent[100],Distance[100],Finishing_time[100];
string color[100];
stack<int> result;
void inputGraph();
void initialize();
void doDFS();
void doDFSvisit(int);
void printPath();
//void printAll();
//void printAdjacencyMatrix();
//void printColor();
//void printDistance();
//void printParent();
int main(void)
{
inputGraph();
//initialize();
doDFS();
printPath();
//printAll();
return 0;
}
void inputGraph()
{
cout<<"Total vertex : ";
cin>>vertex;
cout<<"Total edge : ";
cin>>edge;
int i,j;
for(i=1; i<=edge; i++)
{
int start,finish;
cout<<"Enter start and end node for edge "<<i<<" : ";
cin>>start;
cin>>finish;
adjacency_matrix[start][finish]=1;
}
cout<<"The adjacency matrix is : "<<endl;
for(i=1; i<=vertex; i++)
{
for(j=1; j<=vertex; j++)
{
cout<<adjacency_matrix[i][j]<<" ";
}
cout<<endl;
}
}
void initialize()
{
cout<<"Enter source node : ";
cin>>source;
}
void doDFS()
{
int i,j;
for(i=1;i<=vertex;i++)
{
color[i]="white";
parent[i]=0;
}
time=0;
for(i=1;i<=vertex;i++)
{
if(color[i]=="white")
{
doDFSvisit(i);
}
}
}
void doDFSvisit(int node)
{
int i;
time=time+1;
Distance[node]=time;
color[node]="grey";
for(i=1;i<=vertex;i++)
{
if(adjacency_matrix[node][i]==1)
{
if(color[i]=="white")
{
parent[i]=node;
doDFSvisit(i);
}
}
}
color[node]="black";
//extra line for result
result.push(node);
//
time=time+1;
Finishing_time[node]=time;
}
void printPath()
{
cout<<"Path :"<<endl;
int i;
for(i=0;i<=result.size();i++)
{
cout<<result.top()<<" -> ";
result.pop();
}
cout<<" End"<<endl;
}
My problem :
for input :
6
6
1 2
1 4
2 3
3 4
5 3
5 6
my output should be :
5 6 1 2 3 4 end
but my output is :
5 6 1 2 end
it seems printing values from stacks creates problem . please correct me where i did mistake , Thanks in advance .
[ P.S. : Pic of the directed graph that I used for input , http://imgur.com/fYsICiQ ]
There is mistake in the print_path function.
Your for-loop termination condition checks result(stack)'s size which decrements each loop-iteration by pop calling.
Your print_path function should look like something like this:
void printPath(){
cout<<"Path :"<<endl;
int i;
while(!result.empty()){
cout << result.top() << " -> ";
result.pop();
}
cout<<" End"<<endl;
}
Additionally consider this DFS implementation:
list<size_t> l[N];
bool used[N];
void DFS(size_t s){
if (used[s])
return;
used[s] = true;
for(auto i = l[s].begin(); i != l[s].end(); i++)
if(!used[*i]){
DFS(*i);
}
}
used is global bool array indicating i'th vertex is visited or not. We have no need to color vertexes. We have to know is it already visited or not.
l is adjacency list (see http://www.geeksforgeeks.org/graph-and-its-representations/ )
We run DFS on some vertex.
If it's visited we do nothing.
Else we mark this vertex as visited. And then go deeper running DFS on each vertex adjacent current vertex.
For more information about DFS see https://en.wikipedia.org/wiki/Depth-first_search
Here's how I would implement DFS in C++. First some observations:
I'll use adjacency lists (std::vectors) rather than an adjacency matrix.
Nodes aren't owned by their neighbors. They're assumed to be owned by a parent Graph object.
So, without further ado:
struct Node {
std::vector<Node *> neighbors;
// Other fields may go here.
}
void process(Node * node)
{
// Actual logic for processing a single node.
}
// Of course, in idiomatic C++, this would be a template
// parameterized by a function object, rather than contain
// a hard-coded call to a fixed `process` function.
void depth_first(Node * start)
{
std::stack <Node *> pending = { start };
std::unordered_set<Node *> visited;
while (!pending.empty()) {
Node * current = pending.pop();
process(current);
for (Node * neighbor : current->neighbors)
if (visited.find(neighbor) == visited.end()) {
pending.push (neighbor);
visited.insert(neighbor);
}
}
}
A nice thing about this implementation is that, in order to get BFS, you only need to replace std::stack with std::queue, and leave the rest of the code exactly as is.
I just wrote a code to build a Huffman Tree using MinHeap. When testing I want to output its traversal result.
The algorithm is simple, but my code can't get the right answer. It's strange that the output was different when I set different breakpoints. For instance, it depends on if I set a break point in the loop, such as line 165 input_list.insert(*parent);.
The test input was
4 //number of nodes.
1 1 3 5 //weight of each node.
and the output when debugging it with a breakpoint in the loop is
5
10
1
2
1
5
3
that is correct. But when I just run it without debug, it even didn't have any output. Does anyone know how to explain it?
#include <iostream>
#include <vector>
using namespace std;
#define max_size 100
int sum=0;
class huffman_node
{
public:
int weight;
huffman_node* left_child;
huffman_node* right_child;
huffman_node(){}
huffman_node(int w, huffman_node* l, huffman_node* r):
weight(w),left_child(l),right_child(r) {}
};
vector <huffman_node> node_list;
class minheap
{
public:
minheap()
{
heap=new huffman_node [max_size];
current_size=0;
}
~minheap()
{
delete []heap;
}
void siftdown(int start, int m)
{
int i=start;
int j=2*i+1;
huffman_node temp=heap[i];
while(j<=m)
{
if(j<m && heap[j+1].weight<heap[j].weight)
{
++j;
}
if(temp.weight<=heap[j].weight)
{
break;
}
else
{
heap[i]=heap[j];
i=j;
j=2*i+1;
}
}
heap[i]=temp;
}
void siftup(int start)
{
int j=start;
int i=(j-1)/2;
huffman_node temp=heap[j];
while(j>0)
{
if(heap[i].weight<=temp.weight)
{
break;
}
else
{
heap[j]=heap[i];
j=i;
i=(j-1)/2;
}
heap[j]=temp;
}
}
bool insert(const huffman_node& input)
{
if(current_size==max_size)
{
cout<<"minheap full"<<endl;
return false;
}
heap[current_size]=input;
siftup(current_size);
++current_size;
return true;
}
bool remove_min(huffman_node& output)
{
if(!current_size)
{
cout<<"minheap empty"<<endl;
return false;
}
output=heap[0];
heap[0]=heap[current_size-1];
--current_size;
siftdown(0,current_size-1);
return true;
}
private:
huffman_node* heap;
int current_size;
};
void route_length(huffman_node* &root,int depth)
{
if(root!=NULL)
{
// if(root->left_child==NULL&&root->right_child==NULL)
// {
// sum+=depth*root->weight;
// }
route_length(root->left_child,depth+1);
cout<<root->weight<<endl;
route_length(root->right_child,depth+1);
}
else
{
return;
}
}
int main()
{
minheap input_list;
int n;
cin>>n;
for(int i=0;i<n;++i)
{
int key;
cin>>key;
huffman_node input(key,NULL,NULL);
input_list.insert(input);
cin.get();
}
huffman_node* root;
for(int i=0;i<n-1;++i)
{
huffman_node* parent;
huffman_node out1;
huffman_node out2;
input_list.remove_min(out1);
input_list.remove_min(out2);
node_list.push_back(out1);
node_list.push_back(out2);
parent=new huffman_node(out1.weight+out2.weight,&node_list[node_list.size()-2],&node_list[node_list.size()-1]);
input_list.insert(*parent);
root=parent;
}
route_length(root,0);
// cout<<sum<<endl;
return 0;
}
The problem is that you are using pointers to elements of a vector<huffman_node> and storing these in your data structure (i.e. left and right members of the huffman_node object).
The thing that is randomly killing your program is that std::vector moves values around in memory when you append to it. The contents of the elements of the vectors are preserved, but the location is not. Once it moves the elements, the memory where the vector used to be can be overwritten by whatever (i.e. gdb needs heap memory too) and now the pointers are pointing to garbage.
As a quick sanity check, you can make your code not crash by reserving space in your node_list by calling
node_list.reserve(max_size*2);
in the beginning of main. This is not the right way of developing this piece of code further, but should illustrate the problem.
It would be better if your node_list was a vector<huffman_node*> instead. Or if you changed the left/right members to be vector indices instead of pointers.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 8 years ago.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Improve this question
So I have a homework assignment due tonight and I'm trying to compile it to test but I'm running into a bunch of errors and some of them seem to make zero sense? The errors mention things like: "syntax error before '::'" and the like, but I have never encountered errors like these and have 0 idea on how to fix them.
UnsortedClass.cpp
#include "UnsortedClass.h"
void UnsortedType::UnsortedType()
{
length = 0;
}
bool UnsortedType::IsFull() const
{
return (length == MAX_ITEMS);
}
int UnsortedType::GetLength() const
{
return length;
}
NBA UnsortedType::GetItem(NBA customPlayer, bool& found)
{
bool moreToSearch;
int location = 0;
found = false;
moreToSearch = (location < length);
while (moreToSearch && !found)
{
switch (customPlayer.ComparedTo(info[location]))
{
case LESS :
case GREATER : location++;
moreToSearch = (location < length);
break;
case EQUAL : found = true;
item = info[location];
break;
}
}
return customPlayer;
}
void UnsortedType::MakeEmpty()
{
length = 0;
}
void UnsortedType::PutItem(NBA customPlayer)
{
info[length] = customPlayer;
length++;
}
void UnsortedType::DeleteItem(NBA customPlayer)
{
int location = 0;
while (customPlayer.ComparedTo(info[location]) != EQUAL)
location++;
info[location] = info[length - 1];
length--;
}
void UnsortedType::ResetList()
{
currentPos = -1;
}
NBA UnsortedType::GetNextItem()
{
currentPos++;
return info[currentPos];
}
UnsortedClass.h
#include "NBA.h"
class UnsortedClass //declares a class data type
{
public:
// 8 public member functions
void UnsortedType ( );
bool IsFull () const; //checks if list is full
int GetLength () const ; // returns length of list
NBA GetItem (NBA customPlayer, bool& found); //gets item specified in parameters
void PutItem (NBA customPlayer); //puts NBA player in list
void DeleteItem (NBA customPlayer); //deletes NBA player from list
void ResetList (); //resets list to 0
NBA GetNextItem (); //gets next item after current list position
private:
// 3 private data members
int length;
NBA info[MAX_ITEMS];
int currentPos;
};
NBA.h
#include <string>
using namespace std;
const int MAX_ITEMS = 10;
enum RelationType {LESS, GREATER, EQUAL};
class NBA {
private:
char firstInitial;
string lastName;
string team;
char position;
public:
void set_first_initial(char playerFirstInitial);
void set_last_name(string playerLastName);
void set_team(string teamName);
void set_position(char position);
char get_first_initial();
string get_last_name();
string get_team();
char get_position();
};
The errors I've been receiving are as follows (in picture format as I can't paste the lines without Stackoverflow interpreting it as code)
Constructors don't have a return type specified. Change
void UnsortedType::UnsortedType()
to
UnsortedType::UnsortedType()
Also the class name in its header declaration is wrong; everywhere else says UnsortedType but this says:
class UnsortedClass //declares a class data type