This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I have a 2D fixed size object array of "spot" class
Spot map[row][col];//row & col are dynamic changed integer
I want to pass it to a function
bool isFilled(int row,int col,Spot[row][col]){}
How to define the function? How to delete this array ?Please see my code. Thanks for your help.
Spot.h
#ifndef SPOT_H
#define SPOT_H
class Spot
{
private:
bool isBunny;
int nextCycle;
public:
static const int UP = 0;
static const int RIGHT = 1;
static const int DOWN = 2;
static const int LEFT = 3;
static const int SLEEP = 4;
virtual void setSpot(bool newIsBunny);
Spot();
~Spot();
virtual int getNextCycle();
virtual void setNextCycle();
virtual bool getIsBunny();
virtual void makeBunny();
};
void Spot::setSpot(bool newIsBunny)
{
isBunny = newIsBunny;
nextCycle = UP;
}
Spot::Spot()
{
isBunny = false;
nextCycle = UP;
}
Spot::~Spot()
{
}
void Spot::setNextCycle()
{
if (nextCycle != SLEEP)
{
nextCycle++;
}
}
int Spot::getNextCycle()
{
return nextCycle;
}
bool Spot::getIsBunny()
{
return isBunny;
}
void Spot::makeBunny()
{
if (!isBunny)
nextCycle = UP;
isBunny = true;
}
#endif /* SPOT_H */
Bunny.cpp
#include "Spot.h"
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <boost/algorithm/string.hpp>
using namespace std;
static string line;
static ifstream inFile;
static ofstream outFile;
bool isFilled(int x, int y, Spot **myMap);
int main () {
int numSims = 0;
inFile.exceptions ( ifstream::failbit | ifstream::badbit );
try {
inFile.open ("/home/mike/Desktop/input.txt");
outFile.open ("/home/mike/Desktop/output.txt");
// while(!inFile.eof())
{
getline (inFile,line);
numSims= atoi(line.c_str());
//cout<<"numSims: "<<numSims<<endl;
for (int i = 0;i < numSims;i++)
{
int minPerCycle = 1;
getline (inFile,line);
minPerCycle= atoi(line.c_str());
//cout << "minPerCycle: "<<minPerCycle <<endl;
int row = 0;
int col = 0;
getline (inFile,line);
std::vector<std::string> xy;
boost::split(xy, line, boost::is_any_of(" "));
row=atoi(xy.at(0).c_str());
col=atoi(xy.at(1).c_str());
//cout <<"row: "<< row<<endl;
//cout << "col: "<<col<<endl;
Spot** myMap = new Spot* [col];
for(int i = 0; i < col; ++i)
myMap[i] = new Spot [row];
//std::vector<std::vector<Spot> > myMap(x, std::vector<Spot>(y));
for (int i = 0;i < row;i++)
{
getline (inFile,line);
//cout<<line<<endl;
for (int j = 0;j < col;j++)
{
if (line[j] == 'B')
{
myMap[i][j].setSpot(true);
}
else
{
myMap[i][j].setSpot(false);
}
}
}
int numCycles = 1;
if (isFilled(row,col,myMap))
{
numCycles = 0;
}
while (!isFilled(row,col,myMap))
{
numCycles++;
for (int j = 0;j < row;j++)
{
for (int k = 0;k < col;k++)
{
if (myMap[j][k].getIsBunny())
{ //cout<< j<<" "<<k<<" " <<"true"<<endl;
switch (myMap[j][k].getNextCycle())
{
case Spot::UP :
if (j>0)
myMap[j-1][k].makeBunny();
break;
case Spot::RIGHT :
if (k<col-1)
myMap[j][k + 1].makeBunny();
break;
case Spot::DOWN :
if (j<row-1)
myMap[j+ 1][k].makeBunny();
break;
case Spot::LEFT :
if (k>0)
myMap[j][k - 1].makeBunny();
break;
}
myMap[j][k].setNextCycle();
}
//cout<< j<<" "<<k<<" " <<"outside"<<endl;
}
}
}
int time = numCycles*minPerCycle;
outFile<<"It took " <<time <<" minutes for the bunnies to take over the world!\n";
cout<<"It took " <<time <<" minutes for the bunnies to take over the world!\n";
for(int i=0; i < col; i++) {
delete [] myMap[i];
}
delete myMap;
}
}
inFile.close();
outFile.close();
}
catch (ifstream::failure e) {
cout << "Exception opening/reading file";
}
return 0;
}
bool isFilled(int row, int col,Spot **myMap)
{
for (int i = 0;i < row;i++)
{
for (int j = 0;j < col;j++)
{
if (!myMap[i][j].getIsBunny())
{
//cout<<"true ";
return false;
}
//else
// cout<<"false ";
}
//cout<<endl;
}
return true;
}
Have to tried passing with pointers?
static bool isFilled(int row, int col,Spot** yourMap)
I'm unsure if Spot myMap[row][col] will be accepted by the compiler as row and col seem to be set at runtime.
You may need to allocate memory in the following manner
Spot** myMap = new Spot* [col];
for(int i = 0; i < col; ++i)
myMap[i] = new Spot [row];
Deleting the memory would require you to use a similar for loop but remember to call delete []
I think you can just send a reference to the 2D array into the method you want to use the 2D array with.
bool isFilled(int row, int col, Spot &m){ // if you want a fix position in the array
// Code
}
If you want to delete the array you have to use the delete operator.
First you have to delete all the arrays which the pointer array points to, ie
for(int i=0; i < size; i++) {
delete [] spot[i]; // Depends on what you have called the array
}
Then you have to delete the array of pointers with
delete [] spot;
Spot myMap[row][col];
This is not legal C++ code. You can do this in C99 but not in C++.
You have two basic choices in C++:
Use a one dimensional array that you treat as if it were a 2D array.
Use a ragged 2D array instead of a contiguous 2D array.
The key advantage of using a one dimensional array is that it is fast. This is the way to go if you need speed. Graphics programmers often use this approach because they need that speed. The downside is that you have to convert your 2D indices to a single index. For example, map[i][j] might become map[i*col+j] (row major order) or map[i+j*row] (column major order).
The key advantage of using a ragged array is that the indexing is natural. The downsides are that there are many more pieces of memory to manage and access is considerably slower. With a flattened array, access comprises a small number of integer operations and a single memory lookup. The ragged array requires two memory lookups.
This is C++, so my suggestion is to make your map a class. Provide a non-default constructor with a row and column size that allocates the memory, a destructor (if needed) to clean up. If you use std::vector as the underlying storage mechanism, it will do the allocation and cleanup for you. Provide an overload of operator() to act as an index mechanism into your map. Now the mechanism that you are using to represent your map is hidden. You can start with a vector of vectors, and if that's too slow, switch to the flattened array approach.
Related
The code below – it's a skeleton of a program operating on the dynamic collection of data. The idea is to use a structure containing two fields: the first stores the number of elements in collections, and the second is the actual collection (a dynamically allocated vector of ints). As you can see, the collection is filled with the required amount of pseudo-random data.
Unfortunately, the program requires completion, as the most important function.
Here's what i expect from the function:
if the collection is empty, it should allocate a one-element vector and store a new value in it.
if the collection is not empty, it should allocate a new vector with a length greater by one than the current vector, then copy all elements from the old vector to the new one, append a new value to the new vector and finally free up the old vector.
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
struct Collection {
int elno;
int *elements;
};
void AddToCollection(Collection &col, int element) {
//the first part of the funtion
if (col.elno==0){
col.elements= new int[1];
col.elements[0]= element;
}
//this is the second part but i do not know how to do it.
//Please help me to complete***************
else {
int *temp;
temp = new[];
}
}
void PrintCollection(Collection col) {
cout << "[ ";
for(int i = 0; i < col.elno; i++)
cout << col.elements[i] << " ";
cout << "]" << endl;
}
int main(void) {
Collection collection = { 0, NULL };
int elems;
cout << "How many elements? ";
cin >> elems;
srand(time(NULL));
for(int i = 0; i < elems; i++)
AddToCollection(collection, rand() % 100 + 1);
PrintCollection(collection);
delete[] collection.elements;
return 0;
}
vector container is originally dynamic container. so u can use vector.
Just declare vector variable in structure and use it in AddToCollection function.
struct Collection {
int elno;
std::vector<int> elements;
};
void AddToCollection(Collection &col, int element) {
col.elements.push_back(element);
col.elno++;
}
like this.
Here is what you are looking for:
void AddToCollection(Collection &col, int element)
{
if(col.elements == NULL)
{
col.elements = new int[1];
col.elements[0] = element;
col.elno = 1;
}
else
{
int *newArr = new int[col.elno+1];
for(int i = 0; i < col.elno; i++)
{
newArr[i] = col.elements[i];
}
newArr[col.elno] = element;
delete[] col.elements;
col.elements = new int[col.elno+1];
for(int i = 0; i < col.elno+1; i++)
{
col.elements[i] = newArr[i];
}
delete[] newArr;
newArr = NULL; // avoid dangling pointer
col.elno++;
}
}
For sure using vector container is a great ideea but the exercise require no modification to the main function. The objective of this exercise is to help the student to understand dynamically allocated memory.
This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 8 years ago.
I'm at college and we're learning pointers. Our job was to input a char, compare it to an array and return a pointer to the first reference of that char in the array. But, as I don't like easy things, I've asked my teacher what about having that char more than once in the array.
That's where my headache begins.
So I have this code. The idea is: create a function that compares the input char to the entire array, get the pointers of the references and save them in an array and return that array.
Unfortunately it's not working as I wish :(
What can be wrong?
#include<iostream>
#include<cstdlib>
using namespace std;
char list [10];
int main()
{
initialize();
show();
cout<<search('1');
}
void initialize()
{
int i;
for(i=0; i<10;i++)
{
list[i]='1';
}
}
void show()
{
int i;
for(i=0; i<10;i++)
{
cout<<list[i];
}
}
int* search(char* input)
{
int* result[10];
int i;
char *temp;
for (i=0; i<10; i++)
{
*temp=list[i];
if(strcmp(temp, input) != NULL)
{
result[i]=i;
}
}
return result[];
}
I'm on a mobile device so I can't go into huge detail unfortunately, but you are returning a pointer to an array that you create in the function which goes out of scope at the end of the function.
My massive edit:
As everyone has already stated, a C++ array is actually only a pointer to the first element in the array. As a result, if you return a pointer to an array created in the scope of the function, you are returning a pointer to garbage. If I were doing this I would use a vector, but if I were to be forced into using an array, I would use something like the code below. Hope this helps!
#include <iostream>
#include <cstdlib>
void initialize(char* list) {
for(int i = 0; i < 10; ++i) {
if(i < 4) {
list[i] = '2';
} else {
list[i] = '1';
}
}
}
void show(char *list) {
for(int i = 0; i < 10; ++i) {
std::cout << list[i] << ' ';
}
std::cout << std::endl;
}
// Note the function requires an additional argument that is a pointer
// this is how you can avoid returning a pointer
int search(char input, char* list, char* result) {
int j = 0;
for(int i = 0; i < 10; ++i) {
// comparing characters can be done via ==
if(input == list[i]) {
*(result + j) = list[i];
// You could use result[j], but I used this to show that
// result really is just a pointer to the first element
// of the array. As a result saying result[j] is the same
// as saying I want to deference j elements past the first
// element or *(result + j)
++j; // increment j
}
}
// return how many elements matched
return(j);
}
int main(int argc, char *argv[]) {
char list[10];
char temp[10];
initialize(list);
show(list);
int size = search('1', list, temp);
// create a dynamically sized array containing space for each match
// because we don't know the size at compile time we must use
// a library type or a dynamically sized array
char *result = new char[size];
for(int i = 0; i < size; ++i) {
result[i] = temp[i];
// again you could use result[i]
std::cout << *(result + i) << std::endl;
}
delete[] result; // otherwise you'll get a memory leak
return(0);
}
Currently I am getting an runtime "assertation error"
Here is the error:
I'm reading words from a text file into dynamically allocated arrays.
this block of code is where I am filling the new arrays.
I know the problem is being caused by this block of code and something about my logic is off just can't see what it is.
//fill new arrays
for( int y = 0; y < new_numwords; y++)
{
for( int i = 0; i < NUM_WORDS; i++)
{
if (!strcmp(SentenceArry[i], EMPTY[0]) == 0)
{
New_SentenceArry[y] = SentenceArry[i];
New_WordCount[y] = WordCount[i];
y++;
}
}
}
Also how would I pass this dynamically allocated 2D array to a function? (the code really needs to be cleaned up as a whole)
char** SentenceArry = new char*[NUM_WORDS]; //declare pointer for the sentence
for( int i = 0; i < NUM_WORDS; i++)
{
SentenceArry[i] = new char[WORD_LENGTH];
}
Here is the full extent of the code.. help would be much appreciated!
Here is what is being read in:
and the current output (the output is how it's suppose to be ):
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
#include <cstring>
#include <cctype>
#include <iomanip>
using std::setw;
using std::left;
using std::cout;
using std::cin;
using std::endl;
using std::ifstream;
int main()
{
const int NUM_WORDS = 17;//constant for the elements of arrays
const int WORD_LENGTH = 50;//constant for the length of the cstrings (NEED TO GIVE THE VALUE ZERO STILL!)
short word_entry = 0; //declare counter
short new_numwords= 0; //declare new word count
char EMPTY[1][4]; //NULL ARRAY
EMPTY[0][0] = '\0';//define it as null
char** SentenceArry = new char*[NUM_WORDS]; //declare pointer for the sentence
for( int i = 0; i < NUM_WORDS; i++)
{
SentenceArry[i] = new char[WORD_LENGTH];
}
int WordCount[NUM_WORDS];//declare integer array for the word counter
for(int i = 0; i < NUM_WORDS; i++)//fill int array
{
WordCount[i] = 1;
}
int New_WordCount[NUM_WORDS] = {0};
ifstream read_text("DataFile.txt"); //read in our text file
if (read_text.is_open()) //check if the the file was opened
{
read_text >> SentenceArry[word_entry];
//REMOVE PUNCTUATION BEFORE BEING READ INTO THE ARRAY
while (!read_text.eof())
{
word_entry++; //increment counter
read_text >> SentenceArry[word_entry]; //read in single words of the text file into the array SentenceArry
char* ptr_ch;//declare our pointer that will find chars
ptr_ch = strstr( SentenceArry[word_entry], ",");//look for "," within the array
if (ptr_ch != NULL)//if true replace it with a null character
{
strncpy( ptr_ch, "\0" , 1);
}//end if
else
{
ptr_ch = strstr( SentenceArry[word_entry], ".");//look for "." within the array
if (ptr_ch != NULL)//if true replace it with a null character
{
strncpy( ptr_ch, "\0" , 1);
}//end if
}//end else
} //end while
}//end if
else
{
cout << "The file could not be opened!" << endl;//display error message if file doesn't open
}//end else
read_text.close(); //close the text file after eof
//WORD COUNT NESTED FOR LOOP
for(int y = 0; y < NUM_WORDS; y++)
{
for(int i = y+1; i < NUM_WORDS; i++)
{
if (strcmp(SentenceArry[y], EMPTY[0]) == 0)//check if the arrays match
{
y++;
}
else
{
if (strcmp(SentenceArry[y], SentenceArry[i]) == 0)//check if the arrays match
{
WordCount[y]++;
strncpy(SentenceArry[i], "\0" , 3);
}//end if
}//end if
}//end for
}//end for
//find how many arrays still contain chars
for(int i = 0; i < NUM_WORDS; i++)
{
if (!strcmp(SentenceArry[i], EMPTY[0]) == 0)
{
new_numwords++;
}
}
//new dynamic array
char** New_SentenceArry = new char*[new_numwords]; //declare pointer for the sentence
for( int i = 0; i < new_numwords; i++)
{
New_SentenceArry[i] = new char[new_numwords];
}
//fill new arrays
for( int y = 0; y < new_numwords; y++)
{
for( int i = 0; i < NUM_WORDS; i++)
{
if (!strcmp(SentenceArry[i], EMPTY[0]) == 0)
{
New_SentenceArry[y] = SentenceArry[i];
New_WordCount[y] = WordCount[i];
y++;
}
}
}
//DISPLAY REPORT
cout << left << setw(15) << "Words" << left << setw(9) << "Frequency" << endl;
for(int i = 0; i < new_numwords; i++) //compare i to the array constant NUM_WORDS
{
cout << left << setw(15) << New_SentenceArry[i] << left << setw(9) << New_WordCount[i] << endl; //display the contents of the array SentenceArry
}
//DEALLOCATION
for( int i = 0; i < NUM_WORDS; i++)//deallocate the words inside the arrays
{
delete [] SentenceArry[i];
}
for(int i = 0; i < new_numwords; i++)
{
delete [] New_SentenceArry[i];
}
delete [] SentenceArry; //deallocate the memory allocation made for the array SentenceArry
delete [] New_SentenceArry;//deallocate the memory allocation made for the array New_SentenceArry
}//end main
There are several issues with the code, not withstanding that this could be written using C++, not C with a sprinkling of C++ I/O..
Issue 1:
Since you're using c-style strings, any copying of string data will require function calls such as strcpy(), strncpy(), etc. You failed in following this advice in this code:
for( int y = 0; y < new_numwords; y++)
{
for( int i = 0; i < NUM_WORDS; i++)
{
if (!strcmp(SentenceArry[i], EMPTY[0]) == 0)
{
New_SentenceArry[y] = SentenceArry[i]; // This is wrong
New_WordCount[y] = WordCount[i];
y++;
}
}
}
You should be using strcpy(), not = to copy strings.
strcpy(New_SentenceArry[y], SentenceArry[i]);
Issue 2:
You should allocate WORD_LENGTH for both the original and new arrays. The length of the strings is independent of the number of strings.
char** New_SentenceArry = new char*[new_numwords]; //declare pointer for the sentence
for( int i = 0; i < new_numwords; i++)
{
New_SentenceArry[i] = new char[new_numwords];
}
This should be:
char** New_SentenceArry = new char*[new_numwords]; //declare pointer for the sentence
for( int i = 0; i < new_numwords; i++)
{
New_SentenceArry[i] = new char[WORD_LENGTH];
}
Issue 3:
Your loops do not check to see if the index is going out of bounds of your arrays.
It seems that you coded your program in accordance to the data that you're currently using, instead of writing code regardless of what the data will be. If you have limited yourself to 17 words, where is the check to see if the index goes above 16? Nowhere.
For example:
while (!read_text.eof() )
Should be:
while (!read_text.eof() && word_entry < NUM_WORDS)
Issue 4:
You don't process the first string found correctly:
read_text >> SentenceArry[word_entry]; // Here you read in the first word
while (!read_text.eof() )
{
word_entry++; //increment counter
read_text >> SentenceArry[word_entry]; // What about the first word you read in?
Summary:
Even with these changes, I can't guarantee that the program won't crash. Even it it doesn't crash with these changes, I can't guarantee it will work 100% of the time -- a guarantee would require further analysis.
The proper C++ solution, given what this assignment was about, is to use a std::map<std::string, int> to keep the word frequency. The map would automatically store similar words in one entry (given that you remove the junk from the word), and would bump up the count to 1 automatically, when the entry is inserted into the map.
Something like this:
#include <string>
#include <map>
#include <algorithm>
typedef std::map<std::string, int> StringMap;
using namespace std;
bool isCharacterGarbage(char ch)
{ return ch == ',' || ch == '.'; }
int main()
{
StringMap sentenceMap;
//...
std::string temp;
read_text >> temp;
temp.erase(std::remove_if(temp.begin(), temp.end(), isCharacterGarbage),temp.end());
sentenceMap[temp]++;
//...
}
That code alone does everything your original code did -- keep track of the strings, bumps up the word count, removes the junk characters from the word before being processed, etc. But best of all, no manual memory management. No calls to new[], delete[], nothing. The code just "works". That is effectively 5 lines of code that you would just need to write a "read" loop around.
I won't go through every detail, you can do that for yourself since the code is small, and there are vast amounts of resources available explaining std::map, remove_if(), etc.
Then printing out is merely going through the map and printing each entry (string and count). If you add the printing, that may be 4 lines of extra code. So in all, practically all of the assignment is done with effectively 10 or so lines of code.
Remove below code.
for(int i = 0; i < new_numwords; i++)
{
delete [] New_SentenceArry[i];
}
I'm trying to build and print a 2d array but its showing up as empty when I try to print it out so there's an error somewhere but I cant find it. Can someone help? I added the code for initializing the array.
#ifndef MAZE_HPP_
#define MAZE_HPP_
#include <fstream>
#include <vector>
#include <string>
class Maze
{
public:
Maze(int size);
~Maze() {}
enum Direction { DOWN, RIGHT, UP, LEFT };
// Implement the following functions:
// read maze from file, find starting location
void readFromFile(std::ifstream &f);
// make a single step advancing toward the exit
void step();
// return true if the maze exit has been reached, false otherwise
bool atExit();
// set row and col to current position of 'x'
void getCurrentPosition(int &row, int &col);
//print function
void printMaze();
// You can add more functions if you like
private:
// Private data and methods
int size, rowX, colY;
char matrix[30][30];
};
#endif /* MAZE_HPP_ */
void Maze::readFromFile(std::ifstream &f) {
std::string line;
int i, j;
getline(f, line);
for(i = 0; i < size; i++) {
getline(f, line);
for(j = 0; j < size; j++) {
matrix[j][i] = line[j];
}
}
f.close();
}
void Maze::printMaze() {
int i, j;
for(i = 0; i < size; i++) {
for(j = 0; j < size; j++) {
std::cout << matrix[i][j] << "";
std::cout << "line";
}
std::cout << std::endl;
}
}
The initialization does not matter here although it is good practice. Back to the problem: there can be several reasons
1. You have passed zero or negative number for size in the constructor when you create a Maze object.
2. You have passed positive number for size but forgot to assign it to the size variable in the constructor.
If it enters into the loop in print function and shows the string "line" size times then it means it can not read anything from file.
It would be helpful if you send full code or at least the constructor.
#include <iostream>
#include <vector>
using namespace std;
class PerformSort
{
public:
const vector<int> * p;
vector<int>& getElements(int);
vector<int>& sortArray(vector<int>&);
void printer(vector<int>&);
}firstSort;
vector<int>& PerformSort::getElements (int num)
{
vector<int> elements(num);
for (int i = 0; i < num; i++)
{
cout << "Enter elements into the array: ";
cin >> elements[i];
}
p = &elements;
return p;
}
vector<int>& PerformSort::sortArray (vector<int>& vector)
{
int holder, min;
for (int i = 0; i < (sizeof(vector) - 1); i++)
{
min = i;
for (int j = (i + 1); j < sizeof(vector); j++)
{
if (vector[j] < vector[min])
{
min = j;
}
}
if (min != i)
{
holder = vector[i];
vector[i] = vector[min];
vector[min] = holder;
}
}
return vector;
}
void PerformSort::printer(vector<int>& vector2)
{
for (int i = 0; i < sizeof(vector2); i++)
{
cout << vector2[i] << " ";
}
}
int main ()
{
int numberOfTimes;
cin >> numberOfTimes;
firstSort.printer(firstSort.sortArray(firstSort.getElements(numberOfTimes)));
return 0;
}
This returns the error: "invalid initialization of reference of type from expression of type". My first approach to create a SelectionSort algorithm was to try passing the vector by value (stupidly). After this I started to use pointers instead, after some research. However, this resulted in the aforementioned error. Declaring everything as constant does not seem to resolve the underlying error, despite how, if I understand things correctly, the error lies with temporary references being passed where constant ones are required. Any thoughts on how I might achieve this passing and returning of vectors? (I come from a Java background and am just beginning C++, so forgive me if I have made any obvious errors with regards to the pointers).
Return it by value:
vector<int> PerformSort::getElements (int num)
{
vector<int> elements(num);
for (int i = 0; i < num; i++)
{
cout << "Enter elements into the array: ";
cin >> elements[i];
}
return elements;
}
This will also let you get rid of p, which is a huge can of worms in its own right.
Finally, I notice that you use sizeof(vector) in quite a few places. This won't give you the number of elements in the vector; use vector.size() instead.
Rename the variable vector to something else:
vector<int>& PerformSort::sortArray (vector<int>& wayBetterName)
&
return wayBetterName;
What urged you to name a variable the same as a type?
There's many more other issues with the code.
You don't need pointers, you don't need the references, plus you're better off just using std::sort.