How store class objects in vector<vector<class *>> and access and pass them to function either by reference or value - c++

#ifndef BINARY_TREE_H
#define BINARY_TREE_H
#include<iostream>
#include<vector>
using namespace std;
class Binary_Tree;
static int levelCount=0;
extern vector<vector<Binary_Tree*>> vec;
extern vector<Binary_Tree*> tempVec;
class Binary_Tree
{
public:
Binary_Tree()
{
childNum=0;
data=0;
level=0;
prev=NULL;
next[0]=NULL;
next[1]=NULL;
};
Binary_Tree(int d)
{
childNum=0;
data=d;
level=0;
prev=NULL;
next[0]=NULL;
next[1]=NULL;
levelCount++;
}
void insert_node(int,int,int);
int get_level();
int get_childCount();
friend int set_childNum(Binary_Tree*);
private:
int childNum;
int data;
int level;
Binary_Tree *prev;
Binary_Tree *next[2];
};
#endif // BINARY_TREE_H
Here is the implementation file
#include<iostream>
#include<cmath>
#include "Binary_Tree.h"
using namespace std;
void Binary_Tree::insert_node(int lev, int d, int sib)
{
if(vec.empty())
{
cout<<"You Have to create Root first";
}
else
{
if(set_childNum(vec[lev][sib-1])==0)
{
cout<<"Child cant be created parent Node already has two childs.";
}
else
{
childNum=set_childNum(vec[lev][sib-1]);
data=d;
level=lev+1;
prev=vec[lev][sib];
next[0]=NULL;
next[1]=NULL;
tempVec.clear();
for(int i=0; i<pow(2,(lev+1)); i++)
{
if(i==childNum-1)
{
tempVec.push_back(this);
}
else
tempVec.push_back(vec[lev][i]);
}
vector<vector<Binary_Tree*>>::iterator itr=vec.begin()+(lev+1);
vec.erase(itr);
vec.insert(itr,tempVec);
}
}
}
int set_childNum(Binary_Tree *lstNdAdr)
{
if(lstNdAdr->get_childCount()==0)
return 1;
else if(lstNdAdr->get_childCount()==1)
return 2;
else
return 0;
}
int Binary_Tree::get_level()
{
return level;
}
int Binary_Tree::get_childCount()
{
if(next[0]==NULL)
{
return 0;
}
else if(next[0]!=NULL && next[1]==NULL)
{
return 1;
}
else
{
return 2;
}
}
MAIN.cpp
#include <iostream>
#include<cmath>
#include"Binary_Tree.h"
using namespace std;
vector<vector<Binary_Tree*>> vec;
vector<Binary_Tree*> tempVec;
int main()
{
Binary_Tree tree;
here:
cout<<"Enter your Choice:1.Create Root Of Tree\n"
<<"2.Insert node\n"<<endl;
int choice;
cin>>choice;
switch(choice)
{
case 1:
{
int d;
cout<<"Enter Data to insert: ";
cin>>d;
Binary_Tree treeDummy(d);
tree=treeDummy;
tempVec.push_back(&tree);
vec.push_back(tempVec);
}
break;
case 2:
{
int lev;
int sibbling;
int d;
cout<<"Enter at which level and data and parent's sibling-no.: ";
cin>>lev;
cin>>d;
cin>>sibbling;
if(sibbling>pow(2,lev))
cout<<"Illegal Sibbling Number."<<endl;
else
tree.insert_node(lev,d,sibbling);
}
break;
}
int x;
cin>>x;
if(x==5)
{
cout<<endl<<endl;
goto here;
}
return 0;
}
in above code i am trying to create a binary tree type structure which can be manipulated and traversed dynamically that is any node can be inserted and can be removed at run time (although its incomplete because i am stuck at a problem). While pushing back the tempVec vector the code produces a segmentation fault and i am also doubtful in passing the object stored in vetcor> vec to the functions in the implementation (I am new to Stl and first time dealing with vector of vectors containing pointer to the class types)

The nested vector's entries are only filled if i is set to 1. But you attempt to access its element [0][0] regardless. You have out of bounds access when i is not 1.

There are numerous problems present in your code, that and combined with the poor style and formatting makes it not so fun to debug.
Binary_Tree treeDummy(d);
tree = treeDummy;
tempVec.push_back(&tree);
I'm not sure what you're trying to do here but the above looks wrong. You are shallow copying treeDummy's data over to tree. You'll lose the link to whatever child node tree points to. Afterwards you're pushing that same tree instance into your temporary vector. That means all the elements in your vector ends up pointing to the local variable tree in main. So even if no segfault occurred you would run into aliasing problems since they all refer to the same tree object and not a separate unique BinaryTree instance.
vector< vector<Binary_Tree*> >::iterator itr=vec.begin()+(lev+1);
vec.erase(itr);
vec.insert(itr,tempVec);
Your BinaryTree::insert_node is using an invalidated iterator after performing erase which is undefined behavior.
childNum = set_childNum(vec[lev][sib-1]);
// ...
prev = vec[lev][sib];
The above can access an out-of-bound index in your vector. eg. You push_back a tempVec with only 1 element in it and then call insert_node with sib = 1.
// ...
if(x == 5)
{
cout<<endl<<endl;
goto here;
}
The use of goto is also completely unnecessary here and should be replaced with a traditional while loop that checks for condition != 5.
The higher level problem in your program, however, is that there's no clear constraints and invariants in its design. What assumptions and preconditions do each of those functions need to work? Why use vectors to hold BinaryTree nodes when the class itself should be dealing with that. You should get the overall design sorted out first, otherwise you'll just play whack-a-mole as other bugs crop up.

Related

Unable to access vector value by index

#include<iostream>
#include<vector>
using namespace std;
class Stack
{
public:
int top;
vector<int> v;
Stack(int size)
{
top=0;
cout<<"Enter the values"<<endl;
for(int i=0; i<size; i++)
{
int val;
cin>>val;
v.push_back(val);
top++;
}
}
void push(int val)
{
v.push_back(val);
top++;
}
int pop()
{
int x=v[top];
top--;
return x;
}
void disp()
{
for(int j=top; j<=0; j--)
cout<<v[j]<<' ';
}
};
int main()
{
Stack s(3);
int k=s.pop();
cout<<k;
return 0;
}
I am trying to learn the basics of OOP.
Here, my Stack constructor and push function are working fine, but there is a problem with the pop and disp functions.
I'm assuming that I am using an incorrect syntax to access the elements of a vector(maybe?). Can anyone tell me where I am going wrong?
Also, the value of k always comes out to be 0.
You can use the vector functions
int k = s.back();
s.pop_back();
cout << k;
more informationhttp://www.cplusplus.com/reference/vector/vector/back/
You have a off-by-one index error.
The way you have implemented your class, when there are N items in the stack, the value of top is N.
Hence, top is not a valid index to access the elements of v. You can use:
int pop()
{
int x=v[top-1];
top--;
return x;
}
or
int pop()
{
top--;
int x=v[top];
return x;
}
As some of the other answers say, you can use the built-in vector functions to do these things (see pop_back and back.
However, if you want to define your own, I would use the vector.at(index) function. Addressing the values with the index as you have works, but it doesn't do any bounds checking at() does. Which would solve your problem above where your index isn't correct for the zero-based indexing of a vector.

Different output when set different breakpoints

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.

Segmentation Fault 11 whenever I run this. Would like assistance/feedback

So I'm making a really rudimentary implementation of a circular list. I haven't made the remove function yet. Whenever I run the cpp, I get a seg fault 11. Any feedback would be much appreciated. Thank you.
#include <iostream>
using namespace std;
struct node{
node* next=NULL;
bool tail= false;
int contents;
};
node* start;//start is a pointer that exists at the start of the list before the first element
class CircList{
node *seek;
public:
CircList (){ //creates a list of one node that points to itself
node *b= new node;
b->contents=0;
b->next = b;
start->next=b;
b->tail=true;
}
bool empty(){
if(start->next==NULL){
return true;
}
return false;
}
int size(CircList a){
if(start->next==NULL){
cout<<"size is 0 \n";
return true;
}
seek=start->next;
for(int i=0; i++;){
if(seek->tail==true){
cout<<"size is "<<i;
}
seek=seek->next;
}
return 0;
}
void insert(int pos, int val){
if(start->next ==NULL){//if inseting when the list is empty
node *b= new node;
b->next = b;
b->tail=true;
return;
}
node *b= new node;
b->contents= val;
seek=start->next;
for(int i=0;i<=pos; i++){
if(seek->tail==true){//if inserting at the end
seek->tail=false;
b->tail=true;
seek->next=b;
b->next=start->next;
}
if(pos==i){//if inserting between two nodes
b->next = seek->next;
seek->next = b;
}
seek=seek->next;
}
}
void remove(int a){
seek=start->next;
for(int i=0;i<=a-1; i++){
if(i<a){
seek=seek->next;
}
if(i==a-1){
}
}
}
void display(){
cout<<start->next->contents; //will also be completed in the near future
seek=start->next;
for(int i=0; ;i++){
if(seek->tail==false){
cout<<seek->contents<<"\n";
}
if(seek->tail==true){
cout<<seek->contents<<"\n";
return;
}
}
}
};
That was the .h file. The following is the cpp. I just plugged in numbers to test. I want to get the program running so that I can test how it behaves.
#include <iostream>
#include "CircList.h"
using namespace std;
int main(){
CircList a;
a.insert (5,5);
a.insert (5,5);
a.insert (1,4);
a.insert (20,65);
a.insert (3,7);
a.size(a);
a.display();
}
I kept treating start as a node instead of a pointer. By making start = Null and replacing all the "start->next"'s with "start", I got it to compile and run. But now it's only infinitely inserting nodes with a value of 0 in the contents.
Edit: I fixed it. By changing that weird for loop in the display function to a while loop, it doesn't do infinite inserts of the node in the constructor, anymore. It seems to work decently enough now.
This here causes a seg fault
start->next=b;
because start is NULL at the start of the program so you are de-referencing a null pointer.
instead set start to the first node in your constructor
start = b;
Your global variable start is an uninitialized pointer, yet you dereference it all over the place.

Adjacency list implementation in C++

I am looking for a concise and precise adjacency list representation of a graph in C++. My nodes are just node ids. Here is how I did it. Just want to know what experts think about it. Is there a better way?
This is the class implementation (nothing fancy, right now don't care about public/private methods)
#include <iostream>
#include <vector>
#include <fstream>
#include <sstream>
using namespace std;
class adjList {
public:
int head;
vector<int> listOfNodes;
void print();
};
void adjList :: print() {
for (int i=0; i<listOfNodes.size(); ++i) {
cout << head << "-->" << listOfNodes.at(i) << endl;
}
}
class graph {
public:
vector<adjList> list;
void print();
};
void graph :: print() {
for (int i=0; i<list.size(); ++i) {
list.at(i).print();
cout << endl;
}
}
My main function parses an input file line by line. Where each line is interpreted as following:
<source_node> <node1_connected_to_source_node> <node2_connected_to_source_node <node3_connected_to_source_node> <...>
Here is the main:
int main()
{
fstream file("graph.txt", ios::in);
string line;
graph g;
while (getline(file, line)) {
int source;
stringstream str(line);
str >> source;
int node2;
adjList l;
l.head = source;
while (str >> node2) {
l.listOfNodes.push_back(node2);
}
g.list.push_back(l);
}
file.close();
g.print();
getchar();
return 0;
}
I know I should add addEdge() function inside adjList class instead of directly modifying its variable from main() however, right now I just wonder about the best structure.
EDIT:
There is one shortcoming in my approach. For a complicated graph with large number of nodes, node will indeed be a struct/class and in that case I will be duplicating values by storing the whole object. In that case I think I should use pointers. For example for an undirected graph, I will be storing copies of node objects in the adjList (connection between node 1 and 2 means 1's adjacency list will have 2 and vice versa). I can avoid that by storing pointers of node objects in the adjList instead of the whole object. Check the dfs implementation which get benefited by this approach. There I need to insure that each node gets visited only once. Having multiple copies of the same node will make my life harder. no?
In this case my class definitions will change like this:
#include <iostream>
#include <vector>
#include <fstream>
#include <sstream>
#include <map>
using namespace std;
class node {
public:
node() {}
node(int id, bool _dirty): node_id(id), dirty(_dirty) {}
int node_id;
bool dirty;
};
class adjList {
public:
node *head;
vector<node*> listOfNodes;
void print();
~adjList() { delete head;}
};
void adjList :: print() {
for (int i=0; i<listOfNodes.size(); ++i) {
cout << head->node_id << "-->" << listOfNodes.at(i)->node_id << endl;
}
}
class graph {
public:
vector<adjList> list;
void print();
void dfs(node *startNode);
};
void graph::dfs(node *startNode) {
startNode->dirty = true;
for(int i=0; i<list.size(); ++i) {
node *stNode = list.at(i).head;
if (stNode->node_id != startNode->node_id) { continue;}
for (int j=0; j<list.at(i).listOfNodes.size(); ++j) {
if (!list.at(i).listOfNodes.at(j)->dirty) {
dfs(list.at(i).listOfNodes.at(j));
}
}
}
cout << "Node: "<<startNode->node_id << endl;
}
void graph :: print() {
for (int i=0; i<list.size(); ++i) {
list.at(i).print();
cout << endl;
}
}
And this is how I implemented main() function. I am using a map<> to avoid duplication of objects. Creating a new object only when its not defined earlier. Checking existence of an object by its id.
int main()
{
fstream file("graph.txt", ios::in);
string line;
graph g;
node *startNode;
map<int, node*> nodeMap;
while (getline(file, line)) {
int source;
stringstream str(line);
str >> source;
int node2;
node *sourceNode;
// Create new node only if a node does not already exist
if (nodeMap.find(source) == nodeMap.end()) {
sourceNode = new node(source, false);
nodeMap[source] = sourceNode;
} else {
sourceNode = nodeMap[source];
}
adjList l;
l.head = sourceNode;
nodeMap[source] = sourceNode;
while (str >> node2) {
// Create new node only if a node does not already exist
node *secNode;
if (nodeMap.find(node2) == nodeMap.end()) {
secNode = new node(node2, false);
nodeMap[node2] = secNode;
} else {
secNode = nodeMap[node2];
}
l.listOfNodes.push_back(secNode);
}
g.list.push_back(l);
startNode = sourceNode;
}
file.close();
g.print();
g.dfs(startNode);
getchar();
return 0;
}
SECOND EDIT
After Ulrich Eckhardt suggestion to put adjacency list in node class, here is what I think is a better data structure to store a graph and perform dfs(), dijkstra() kind of operations. Please note that adjacency list is merged in node class.
#include <iostream>
#include <vector>
#include <fstream>
#include <sstream>
#include <map>
using namespace std;
class node {
public:
node() {
}
node(int id, bool _dirty): node_id(id), dirty(_dirty) {
//cout << "In overloaded const\n";
}
int node_id;
bool dirty;
vector<node*> listOfNodes;
};
class graph {
public:
vector<node*> myGraph;
void dfs(node* startNode);
};
void graph::dfs(node* startNode) {
startNode->dirty = true;
for (int j=0; j<startNode->listOfNodes.size(); ++j) {
if (!startNode->listOfNodes.at(j)->dirty) {
dfs(startNode->listOfNodes.at(j));
}
}
cout << "Node: "<<startNode->node_id << endl;
}
Can we do better than this?
There are a few things that could be improved, but in general your approach is reasonable. Notes:
You are using int as index into a container, which will give you warning from some compilers, because the size of a container could exceed the size representable as int. Instead, use size_t.
Rewrite your for (int i=0; i<list.size(); ++i) to for(size_t i=0, size=list.size(); i!=size; ++i). Using != instead of < will work with iterators. Reading and storing the size once makes it easier to debug and possibly even more efficient.
Inside the loop to print, you have list.at(i).print();. The list.at(i) will verify the index is valid and raise an exception when not. In this very simple case, I am sure that the index is valid, so using list[i] instead is faster. Also, it implicitly documents that the index is valid and not that you expect it to be invalid.
The print() functions should be constant.
I don't understand what the int head is. Is this some kind of ID for the node? And isn't the ID simply the index inside graph::list? If it is the index, you could compute that on demand using the address of the element minus the address of the first element, so there's no need to store it redundantly. Also, consider validating that index when reading, so you don't have any edges going to a vertex that doesn't exist.
If you don't care about encapsulation on a node-level (which is reasonable!), you could also make this a struct, which saves some typing.
Storing pointers instead of indices is tricky but could improve speed. The problem is that for reading, you might need a pointer to a vertex that doesn't exist yet. There is a hack that allows doing that without using additional storage, it requires first storing the indices in the pointer values (using reinterpret_cast) and after reading, making a second pass on the data where you adjust these values to the actual addresses. Of course, you can also use the second pass to validate that you don't have any edges going to vertices that don't exist at all (which is a place where the at(i) function becomes useful) so this second pass to verify some guarantees is a good thing anyway.
On explicit request, here's an example for how to store an index in a pointer:
// read file
for(...) {
size_t id = read_id_from_file();
node* node_ptr = reinterpret_cast<node*>(id);
adjacency_list.push_back(node_ptr);
}
/* Note that at this point, you do have node* that don't contain
valid addresses but just the IDs of the nodes they should finally
point to, so you must not use these pointers! */
// make another pass over all nodes after reading the file
for(size_t i=0, size=adjacency_list.size(); i!=size; ++i) {
// read ID from adjacency list
node* node_ptr = adjacency_list[i];
size_t id = reinterpret_cast<size_t>(node_ptr);
// convert ID to actual address
node_ptr = lookup_node_by_id(id);
if(!node_ptr)
throw std::runtime_error("unknown node ID in adjacency list");
// store actual node address in adjacency list
adjacency_list[i] = node_ptr;
}
I'm pretty sure that this works in general, though I'm not 100% sure if this is guaranteed to work, which was why I'm reluctant to post this here. However, I hope this also makes clear why I'm asking what exactly "head" is. If it is really just the index in a container, there is little need for it, neither inside the file nor in memory. If it is some kind of name or identifier for a node that you retrieved from a file, then you absolutely need it, but then you can't use it as index, the values there could as well start their IDs with 1 or 1000, which you should catch and handle without crashing!

Segmentation Fault in Loop's Condition

The following code is to sort a linked list after creating it. The sorting algorithm used is somewhat similar to Bubble Sort. I am checking the two consecutive nodes and swapping them if necessary. I used the debugger which told me that the fault is raised while condition checking for the loops which are used while sorting.
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<conio.h>
using namespace std;
struct link_list
{
char value[20];
struct link_list *next;
};
int main()
{
struct link_list *head=NULL;
int i,j;
char input[20];
char ch;
struct link_list *loop_var,*temp2,*prev_node,*temp4=NULL;
temp3=NULL;
do
{
cout<<"\nEnter the string you want to insert";
cin>>input;
cout<<"\nDo you want to continue entering?";
cin>>ch;
if (head==NULL)
{
head=new link_list;
strcpy(head->value,input);
head->next=NULL;
continue;
}
for (loop_var=head;loop_var->next!=NULL;loop_var=loop_var->next);
temp2=new link_list;
loop_var->next=temp2;
strcpy(temp2->value,input);
temp2->next=NULL;
}while(ch=='y' || ch=='Y');
for (loop_var=head;loop_var->next!=NULL;loop_var=loop_var->next)
{
cout<<loop_var->value<<"\n";
}
cout<<loop_var->value<<"\n";
char arr[20];
for (loop_var=head;loop_var->next!=NULL;loop_var=loop_var->next)
{
cout<<"\nLoop1";
for (temp4=head;temp4->next!=NULL;temp4=temp4->next)
{
cout<<"\nLoop2";
temp2=temp4;
if (strcmp(temp2->value,temp2->next->value)>0)
{
cout<<"\nSwap Enter";
if (temp2==head && temp2->next->next==NULL)
{
cout<<"\nSpecial1";
temp2->next->next=temp;
temp2->next=NULL;
}
else if (temp2==head)
{
cout<<"\nSpecial2";
head=temp2->next;
temp2->next=head->next;
head->next=temp2;
}
else if (temp2->next->next==NULL)
{
cout<<"\nSpecial3";
prev_node->next=temp2->next;
prev_node->next->next=temp2;
temp2->next=NULL;
}
else
{
cout<<"\nNormal1";
prev_node->next=temp2->next;
temp2->next=prev_node->next->next;
prev_node->next->next=temp2;
cout<<"\nNormal2";
}
}
prev_node=temp4;
cout<<"\nLoop2PreExit";
fflush(stdin);
cout<<"\nLoop2Exit";
}
cout<<"\nLoop1Exit";
}
for (loop_var=head;loop_var->next!=NULL;loop_var=loop_var->next)
{
cout<<loop_var->value<<"\n";
}
cout<<loop_var->value;
getch();
}
temp2->next->next=temp;
"temp" is not defined anywhere... if your compiler filled in that hole for you, then this is what is causing your loop's condition to segfault.
Also, naming every other variable "temp#" is an easy way to have mistakes like this.