# Sorting a 2d vector, pointer trouble

• 12-16-2011
Imara
Sorting a 2d vector, pointer trouble
Hi. Iīm kinda new to the pointer and multidimensional arrays. I need an input for the number and dimensions of an array. Than scan these and, sort the vectors and print them again. Only, every time I run the programm, it gets stuck and stops.

Hereīs my code
Code:

``` #include <stdio.h> #include <stdlib.h> #include <math.h> void swap (double **p, double **q);                            /* wissel de pointer waardes om */ double length (double v[], int dim);                            /* bepaal de lengtes van de vectoren */ int main (void) {     static int dim, num;     int i, j;     double **w, *v;     scanf ("%d %d", &dim, &num);                                /* read N and M */     w = calloc (num, sizeof (double *));                        /* allocate array of M pointers */     v = calloc (num, sizeof (double ));     for (i = 0; i < num; i++)     {         /* allocate space for N dimensional vector */         w[i] = calloc (dim, sizeof (double));         /* read the vector */         for (j = 0; j < dim; j++)         {             scanf ("%le", &w[i][j]);         }     }     for (i = 0; i < num; i++){         v[i] = length(w[i], dim);     }   /* acces the lengths and swap length and w vector in order*/     for (i = 0; i < num - 1; ++i){         for (j = num - 1; j > i; --j){                 if (v[j-1] > v[j])                 {                     swap(&w[j-1], &w[j]);                 }         }     }     for (i = 0; i < num; ++i){         for(j = 0; j < dim; ++j){             printf("%le", w[i][j]);         }     }     return 0; } void swap(double **p, double **q) {     double *tmp = 0;     *tmp = **p;     **p = **q;     **q = *tmp; } double length (double v[], int dim) {     int i;     double wl = 0.0;     for (i = 0; i < dim; ++i)         {             wl += ((v[i]) * (v[i]));         }         wl = sqrt(wl);     return wl; }```
Iīve been stuck on this for quite a while. Thanks in advance!
• 12-16-2011
nonoob
Try printing out using %lf. Also put a space after it. Also I would suggest putting in a new-line so that the output looks more like a matrix...
Code:

```    for (i = 0; i < num; ++i){         for(j = 0; j < dim; ++j){             printf("%lf ", w[i][j]);         }     printf("\n");     }```
You might want to look into making sure the output gets shown before the window disappears which is what I think is happening.
• 12-16-2011
Imara
I changed the printing part to

Code:

```    for (i = 0; i < num; i++){         for(j = 0; j < dim; j++){             printf("%lf ", w[i][j]);         }         printf("\n");     }```
so itīll also print more in a matrix, but it gives back only zeros. Also the assignment is in scientific notation, but that is the least of my worries right now, but thanks, the printing seems neater now
• 12-16-2011
nonoob
I would use %lf in the scanf. I don't know what %le does.
• 12-16-2011
Imara
The scanf part was the bit that was assigned as a task to us, so that should be righ. It scans in as a long e notation, so the scientific 0.0000000e00
• 12-16-2011
Tclausex
In swap() you declare tmp and point it to 0 (NULL). You then attempt to dereference tmp and assign a value to the address of 0. All you need to do is swap pointers, not values. Try
Code:

`tmp = *p ;`
and so on.
• 12-16-2011
Imara
Iīm sorry, that was actually the part that I already changed whilst waiting for reply, and it still doesnīt work. Hereīs the code I have currently

Code:

``` #include <stdio.h> #include <stdlib.h> #include <math.h> void swap (double **p, double **q);                            /* wissel de pointer waardes om */ double length (double v[], int dim);                            /* bepaal de lengtes van de vectoren */ int main (void) {     static int dim, num;     int i, j;     double **w, *v;     scanf ("%d %d", &dim, &num);                                /* read N and M */     w = calloc (num, sizeof (double *));                        /* allocate array of M pointers */     v = calloc (num, sizeof (double ));     for (i = 0; i < num; i++)     {         /* allocate space for N dimensional vector */         w[i] = calloc (dim, sizeof (double));         /* read the vector */         for (j = 0; j < dim; j++)         {             scanf ("%lf", &w[i][j]);         }     }     for (i = 0; i < num; i++){         v[i] = length(w[i], dim);     }   /* acces the lengths and swap length and w vector in order*/     for (i = 0; i < num - 1; ++i){         for (j = num - 1; j > i; --j){                 if (v[j-1] > v[j])                 {                     swap(&w[j-1], &w[j]);                 }         }     }     for (i = 0; i < num; i++){         for(j = 0; j < dim; j++){             printf("%lf ", w[i][j]);         }         printf("\n");     }     return 0; } void swap(double **p, double **q) {     double *tmp;     tmp = *p;     *p = *q;     *q = tmp; } double length (double v[], int dim) {     int i;     double wl = 0.0;     for (i = 0; i < dim; ++i)         {             wl += ((v[i]) * (v[i]));         }         wl = sqrt(wl);     return wl; }```
• 12-16-2011
Tclausex
What does "it doesn't work" mean? It works for me just fine now. Are the results not as expected? If so, what is your sample data?

By the way, whenever you dynamically allocate memory, there is a chance at failure. Whenever there is a chance of failure on something, you should be checking for it. So check that every call to calloc doesn't return NULL.
• 12-16-2011
Imara
At first it didnīt finish the program at all. Now it only returns 0īs, while I need the scanned values, but I canīt find anything wrong with the scan or print functions. Iīll check the callocs, u mean by using assert?
• 12-16-2011
Imara
I inserted the asserts, but the outcome of the code did not change.

My program once more:

Code:

```#include <stdio.h> #include <stdlib.h> #include <math.h> #include <assert.h> void swap (double **p, double **q);                            /* wissel de pointer waardes om */ double length (double v[], int dim);                            /* bepaal de lengtes van de vectoren */ int main (void) {     static int dim, num;     int i, j;     double **w, *v;     scanf ("%d %d", &dim, &num);                                /* read N and M */     w = calloc (num, sizeof (double *));                        /* allocate array of M pointers */     assert (w != NULL);     v = calloc (num, sizeof (double ));     assert (v != NULL);     for (i = 0; i < num; i++)     {         /* allocate space for N dimensional vector */         w[i] = calloc (dim, sizeof (double));         assert (w[i] != NULL);         /* read the vector */         for (j = 0; j < dim; j++)         {             scanf ("%lf", &w[i][j]);         }     }     for (i = 0; i < num; i++){         v[i] = length(w[i], dim);     }   /* acces the lengths and swap length and w vector in order*/     for (i = 0; i < num - 1; ++i){         for (j = num - 1; j > i; --j){                 if (v[j-1] > v[j])                 {                     swap(&w[j-1], &w[j]);                 }         }     }     for (i = 0; i < num; i++){         for(j = 0; j < dim; j++){             printf("%lf ", w[i][j]);         }         printf("\n");     }     return 0; } void swap(double **p, double **q) {     double *tmp;     tmp = *p;     *p = *q;     *q = tmp; } double length (double v[], int dim) {     int i;     double wl = 0.0;     for (i = 0; i < dim; ++i)         {             wl += ((v[i]) * (v[i]));         }         wl = sqrt(wl);     return wl; }```
my input is:
3 5
4 4 4
2 4 2
1 1 9
-1 -2 5
1 1 1

and my output should then be

1.00000e+00 1.00000e+00 1.00000e+00
2.00000e+00 4.00000e+00 2.00000e+00
-1.00000e+00 -2.00000e+00 5.00000e+00
4.00000e+00 4.00000e+00 4.00000e+00
1.00000e+00 1.00000e+00 9.00000e+00

I know I should change the lf to le then, but thats not my biggest concern at the moment. My concern is, my output is:
0.00000e+00 0.00000e+00 0.00000e+00
0.00000e+00 0.00000e+00 0.00000e+00
0.00000e+00 0.00000e+00 0.00000e+00
0.00000e+00 0.00000e+00 0.00000e+00
0.00000e+00 0.00000e+00 0.00000e+00
• 12-16-2011
Imara
New and improved code:

Code:

```void swap (double **p, double **q);                            /* wissel de pointer waardes om */ double length (double v[], int dim);                            /* bepaal de lengtes van de vectoren */ int main (void) {     static int dim, num;     int i, j;     double **w, *v;     scanf ("%d %d", &dim, &num);                                /* read N and M */     w = calloc (num, sizeof (double *));                        /* allocate array of M pointers */     assert (w != NULL);     v = calloc (num, sizeof (double ));     assert (v != NULL);     for (i = 0; i < num; i++)     {         /* allocate space for N dimensional vector */         w[i] = calloc (dim, sizeof (double));         assert (w[i] != NULL);         /* read the vector */         for (j = 0; j < dim; j++)         {             scanf ("%le", &w[i][j]);         }     }     for (i = 0; i < num; i++){         v[i] = length(w[i], dim);     }   /* acces the lengths and swap length and w vector in order*/     for (i = 0; i < num - 1; ++i){         for (j = num - 1; j > i; --j){                 if (v[j-1] > v[j])                 {                     swap(&w[j-1], &w[j]);                     swap(&v[j-1], &v[j]);                 }         }     }     for (i = 0; i < num; i++){         for(j = 0; j < dim; j++){             printf("%e ", w[i][j]);         }         printf("\n");     }     return 0; } void swap(double **p, double **q) {     double *tmp;     tmp = *p;     *p = *q;     *q = tmp; } double length (double v[], int dim) {     int i;     double wl = 0.0;     for (i = 0; i < dim; ++i)         {             wl += ((v[i]) * (v[i]));         }         wl = sqrt(wl);     return wl; }```
I tested the scanning, it works now, the printing is fine as well. Even the calculating of the vector length works. The problem is that the vector gets sorted, but kinda half baked. The problem has to be in the bubble sort or the swap, can anyone help???
• 12-16-2011
Imara
for clarity, my outcome is:
2.00000e+000 4.00000e+000 2.00000e+000
4.00000e+000 4.00000e+000 4.00000e+000
1.00000e+000 1.00000e+000 9.00000e+000
1.00000e+000 1.00000e+000 1.00000e+000
-1.00000e+000 -2.00000e+000 5.00000e+000
• 12-16-2011
Tclausex
You can't use swap() on v[] as it is an array of doubles, not double pointers. Do you need 2 separate arrays or can you just eliminate v[] and calloc dim+1 for w[]? Then one element is reserved for the length and is bound to the data when you swap.
• 12-17-2011
Imara
Thank you so much! It works now!!