views:

4600

answers:

7

I'm writing a merge sort function, and right now I am just using a test case array (there is no input - this is static, for now). I don't know how to pass an array as an argument. Here is my code right now:

//merge sort first attempt

#include <iostream>
#include <algorithm>
#include <vector>

int mergeSort(int[]);
int main()
{
int originalarray[] = {1, 3, 5, 7, 9, 2, 4, 6, 8, 10};
mergeSort(originalarray[]);
}

int mergeSort(int[] originalarray)
{
int num = (sizeof(originalarray)/sizeof(int));
std::vector<int> original(num);

if (num > 2) {
    return num;
}

// Fill the array using the elements of originalarray
// This is just for demonstration, normally original will be a parameter,
// so you won't be filling it up with anything.
std::copy(originalarray, originalarray + num, original.begin());

// Create farray and sarray of the appropriate size
std::vector<int> farray(num / 2);
std::vector<int> sarray(num - farray.size());

// Fill those using elements from original
std::copy(original.begin(), original.begin() + farray.size(), farray.begin());
std::copy(original.begin() + farray.size(), original.end(), sarray.begin());

mergeSort(farray);
mergeSort(sarray);

}

Note that this mergeSort function is not functional, as I have not figured out how to merge them yet (that's my assignment). I would like to get my two vectors sorted before I deal with that, and I can't compile this because of my need to pass an array as an argument. I don't understand pointers, so if that is the solution, my excuse is ignorance. I'm learning programming right now, with C++ as a first language, and only have a basic grasp of the language's features. Thanks for the help.

+3  A: 

You should not use sizeof(originalarray)/sizeof(int) like that. It'll only work for statically declared arrays (the size is known at compile time). You have to pass the size along with it. Why don't you just make a vector out of the array and pass it instead?

Side Note: As a rule of thumb, always note that sizeof will be translated at compile time. So there's no way it could know the size of the array passed as an argument.

Mehrdad Afshari
I don't know what you mean by that. Should I just std::copy all the elements into a vector and pass that? How do you use sizeof() with a vector?
Hooked
You don't use sizeof on vector. v.size() will get the size. You should either do that, or if you want to pass an array, pass the size as another parameter.
Mehrdad Afshari
A: 
  • When you pass arrays to functions, they decay to pointers to the first element of the array, the notation notwithstanding. So, your sizeof doesnot work as expected.

  • When you pass in an array, it is best to pass in the array size, so that you know where to stop. Add it as an additional parameter.

dirkgently
+3  A: 

I see you include <vector>. I suggest you do away with all uses of arrays and only use the vector class. You can see examples of how to use STL containers such as vector here.

Assaf Lavie
I strongly concur.
Dan
+3  A: 
Charlie Martin
I think you overestimate my knowledge, because I have know idea what you just said. I'm currently learning programming right now, and am not onto pointers or the OOP parts of C++ yet.
Hooked
Ah. Okay, I'll add some.
Charlie Martin
That's a really good breakdown of arrays in C++. I'm glad I use .NET/Java! :)
AlexW
Thanks for the kind words, Alex, but actually understanding this would make a big difference to your understanding of Java/C# as well. For example, what to you get when you sayObject a = new Object();in Java. What is 'a' really?
Charlie Martin
A: 

In addition to all the answers above, you might also want to check out the Q&As on arrays from c-faq.com: http://c-faq.com/aryptr/index.html

jaux
A: 

Unfortunately, it's very hard to do exactly what you want to do in C or C++. You can pass around a fixed-size array like this:

int mergeSort(int originalarray[20])
{
    // do something
}

However, your array's size is not defined by a number, it's defined by the number of elements in initialization list.

The thing to do in your case (even though it's really a wrong thing to do) is to do it in two steps:

int originalarray[] = {1, 3, 5, 7, 9, 2, 4, 6, 8, 10};
const size_t arraySize = sizeof originalarray / sizeof originalarray[0];
int mergeSort(int array[arraySize])
{
    // do something
}

Too bad it will not do what you need done: passing the array to a function like this makes a copy of the array, and the point of sorting would be to change the original array.

In truth, you cannot go any further without understanding the concept of "pointer".

The function you need to develop really should be like this:

int originalarray[] = {1, 3, 5, 7, 9, 2, 4, 6, 8, 10};
const size_t arraySize = sizeof originalarray / sizeof originalarray[0];

int mergeSort(int *array, const size_t size)
{
    // do something
}

mergeSort(&(originalArray[0]), arraySize);

In other words, you pass a pointer to first element, and the number of elements.

Alternatively, you can deal with vectors. Vector encapsulates the same two things (pointer to first element and size) in a single entity called "object". Plus, it manages memory for you, so you can extend the number of elements as you need. This is the C++ way. Too bad you can't initialize a vector with {...} like you can an array.

Arkadiy
A: 

Looks like you're using both dynamically allocated arrays and vectors, when I believe just using std::vector will be enough.

First, let your input array be changed to a std::vector, and fill it with your input data.

int main()
{
   std::vector<int> originalarray;
   for (int data = 1; data <= 10; data++)
   {
      originalarray.push_back(data);
   }
   mergeSort(originaldata);
}

Now it's important to declare your mergesort function to take a reference to a std::vector.

int mergeSort(std::vector<int>& originalarray)
{
   // The rest of your code, note that now you are passing 
   // in your array for sorting, so you can continue with your code to split
   // the vector into farray and sarray

   // then call sort on your halves.
   mergeSort(farray);
   mergeSort(sarray);

   // I'm guessing at this point you'd write code to combine your farray sarray, and
   // put it back into originalarray...don't forget to clear original array first!
}

Just a note, looks like you're not doing an inplace sort, so expect your sort to take a while since you're copying out a lot of data.

Snazzer