Sorting an array of pointers

Hello!

Dear all, i have a little problem with sorting. although i tried a really long time, i simply couldnt find my mistake... it would be very nice if somebody of you could help me!

I have a vector R of real numbers. as i want to keep the structure of R, i want to sort a vector of pointers, such that the first pointer in the vector points to the minimum, the second to the second minimum, etc, and the last pointer to the largest value of R.
I try to use the C++-STL-Library function "sort". however, it does not give out what i want. does somebody have a clue whats wrong in my code?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
#include <algorithm>
//#include <vector>
using namespace std;

void printvec(double* xbeg, int n);
void printvecpt(double** xbeg, int n);
bool mycomparefunction (double * a, double *b);

int main () {
  int N = 6;
  double R[] = {2.2, 1.5, 3.2,0.5,1.,1.8};//vector of numbers
  double * Rit;  Rit = R;
  
  double * Rpt[N];
  double ** Rptpt = Rpt;
  for(int i = 0; i < N; ++i){
    *Rptpt = Rit; ++Rit; ++Rptpt;
  } // after this loop, Rpt is a vector of pointers such that
    // Rpt[0] = &R[0], ... , Rpt[5] = &R[5]
    
  printvec(R,N);
  printvecpt(Rpt,N); // print R and *Rpt (yields the same)
  cout << " ------------ \n";
 
  sort(Rpt, Rpt+N, mycomparefunction); // should sort Rpt such that
         // Rpt[0] = &(min(R)), ... , Rpt[5] = &(max(R))
         // R itself is not changed

  printvec(R,N); // should print R, not changed
  printvecpt(Rpt,N); // should print sorted R, unfortunately, doesnt work...
  return 0;
}

bool mycomparefunction (double * a,double * b) { return ( (*a) < (*b)); }

void printvec(double* xbeg, int n){//simply prints out the vector
   double * t=xbeg;
   for(int i = 1; i <= n; ++i){ cout << " " << *t;  ++t;   }
   cout << " \n"; }

void printvecpt(double** x, int n){ printvec(*x, n);}


a typical output will be
1
2
3
 2.2 1.5 3.2 0.5 1 1.8
 2.2 1.5 3.2 0.5 1 1.8
 2.2 1.5 3.2 0.5 1 1.8
 0.5 1 1.8 6.42285e-323 6.95321e-310 6.95321e-310


Those vectors will be really huge, thats why i use C-style vectors. (i guess thats faster(?) )

thanks for your help!

regards, C.
std::sort sorts elements in selected distance, in your case you try to sort pointers :)

Can you guess result of the following construction:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

#include <iostream>

int main()
{
    int *ptr1;
    int val1 = 10;
    ptr1 = &val1;
    int *ptr2;
    int val2 = 100;
    ptr2 = &val2;
    if(ptr1 > ptr2)
        std::cout << "Ooops\n";
    return 0;
}



I hope You get reason of your problem
hello dennis,

thank you for your answer. i am aware of the difference between pointers and dereferenced pointers.

i think you missed that i am using my personal comparison function
bool mycomparefunction (double * a,double * b) { return ( (*a) < (*b)); }

thanks for considering again.

C.
Uh, you know? You could have just done
1
2
for(int i = 0; i < N; ++i)
    *Rptpt++=R+i;

Avoid more than one semicolon per line like the plague, and definitely avoid this:
void printvecpt(double** x, int n){ printvec(*x, n);}

Anyway, the problem is not std::sort(). The problem is your printvecpt() function. When you call it, you're dereferencing the pointer pointer (not a typo) you pass, but there's a problem:

Before sort:
R=0, ..., R+N-1=N-1
Rpt[0]=0, ..., Rpt[N-1]=N-1
After sort:
Rpt[0]=3, Rpt[1]=4, Rpt[2]=1, ...

You're not actually printing each dereferenced element, you're printing the array that starts at **Rpt, which is the same as R+3. You can verify this by calling printvec(R+3,N). It will give you the same result.
Last edited on
> Avoid more than one semicolon per line like the plague

I have to disagree with that. It is useful in certain situations. Probably good advice for the novice, though. But I like this style for a WindowProc:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
LRESULT CALLBACK WindowProc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp )
{
    switch (msg)
    {
    case WM_CREATE:      wmCreate(      hwnd, wp, lp ); break;
    case WM_SIZE:        wmSize(        hwnd, wp, lp ); break;
    case WM_PAINT:       wmPaint(       hwnd, wp, lp ); break;
    case WM_LBUTTONDOWN: wmLButtonDown( hwnd, wp, lp ); break;
    case WM_MOUSEMOVE:   wmMouseMove(   hwnd, wp, lp ); break;
    case WM_LBUTTONUP:   wmLButtonUp(   hwnd, wp, lp ); break;
    case WM_RBUTTONDOWN: wmRButtonDown( hwnd, wp, lp ); break;
    case WM_MBUTTONDOWN: wmMButtonDown( hwnd, wp, lp ); break;
    case WM_MOUSEWHEEL:  wmMouseWheel(  hwnd, wp, lp ); break;
    case WM_COMMAND:     wmCommand(     hwnd, wp, lp ); break; //(menu.c)
    case WM_DESTROY:     wmDestroy(     hwnd, wp, lp ); break;
    default:      return DefWindowProc( hwnd, msg, wp, lp );
    }
    return 0;
}

Yeah, but that at least is formatted nicely. It's not hard to see where everything begins and ends.
Look at this, on the other hand:
for(int i = 1; i <= n; ++i){ cout << " " << *t; ++t; }
I completely missed the ++t when I was reformatting and removed the braces when I shouldn't have. Traitorous formatting.
I usually don't object to style unless it actually makes it hard to know what's going on.
I see what you mean. That's the whole point after all, to make things easier to read. Normally when I've put a couple statements on the same line initially, I end up breaking them into separate lines later on.
i think you should change you function printvecpt as follows:

void printvecpt(double** x, int n)
{
//printvec(*x, n);
for(int i = 1; i <= n; ++i)
{
cout << " " << **x;
++x;
}

}
hello,

oh damn... i thought the error is somehow in my way to call the sort function. but i could have guessed it from the output. thank you very much helios for finding my error and thanks for the code snippet to generate the vector Rpt (i thougth there must be an easier way...).

thank you wydkd for the corrected printvecpt routine.

regards,
C.
Topic archived. No new replies allowed.