Reputation: 37
I am trying to merge two sorted arrays using pointers. The third loop is working food upto first arr[5] but then show garbage values afterwards. is the sorting techniqure wrong or am I using pointers incorrectly?
#include<iostream>
using namespace std;
int main() {
int arr1[] = { 1,3,4,6 };
int arr2[] = { 2,3,4,5 };
int n1 = 4;
int n2 = 4;
int arr3[10];
int* endptr = &arr1[0];
int* endptr2 = &arr2[0];
int* endptr3 = arr3;
int k = 0;
while (endptr < &arr1[n1-1] &&endptr2 < &arr2[n2-1]) {
if (endptr[0] < endptr2[0]) {
endptr3[k++] = endptr[0];
endptr++;
}
else {
endptr3[k++] = endptr2[0];
endptr2++;
}
}
while (endptr < &arr1[n1 - 1]) {
endptr3[k++] = endptr[0];
endptr++;
}
while (endptr2 < &arr2[n2 - 1]) {
endptr3[k++] = endptr[0];
endptr2++;
}
cout << arr3[5];
}
I got the results up to first 6 elements and then get garbage values.
Upvotes: 2
Views: 139
Reputation: 10028
The way you are using the pointers is negatively affecting your thought process.
Let’s abstract it to a function to help make it cleaner:
void merge(
int * first1, int * last1, // elements of array1
int * first2, int * last2, // elements of array2
int * dest ) // where to put sorted data
This is the “iterator” idiom used by C++ algorithms. first
points to the first element. last
points to one-past the last element. (And we assume that dest
points to enough space to contain the results.) So:
int array1[] = { 1,3,4,6 };
int array2[] = { 2,3,4,5,7 };
int array3[9]; // enough room for array1+array2
merge(
array1, array1+4, // first array has 4 elements
array2, array2+5, // second array has 5 elements
array3 ); // destination array has 4+5=9 elements
C++ actually gives us a couple of functions to get the first and last pointers to whatever underlying sequence container you’ve got:
merge(
std::begin(array1), std::end(array1),
std::begin(array2), std::end(array2),
std::begin(array3) );
Now we can reconsider our merge algorithm.
void merge(...)
{
// while both array1 and array2 have elements:
while ((first1 != last1) and (first2 != last2))
{
if (*first2 < *first1)
*dest++ = *first2++;
else
*dest++ = *first1++;
}
// if array1 has any leftover elements:
while (first1 != last1)
*dest++ = *first1++;
// if array2 has any leftover elements:
while (first2 != last2)
*dest++ = *first2++;
}
In particular, notice:
first
and last
pointers directly. When first == last
, there are no elements, since last
is one-past the end of the source array.if (first2[0] < first1[0])
but that is less idiomatic than just using the *
operator.Note also how we kept the test condition to a strict less-than comparison. That has ramifications for generic programming (for example, merge sorting in non-increasing order), but I’ll leave it at that for today...
Upvotes: 4