# Thread: Sorting a 2d vector, pointer trouble

1. ## 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));
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!

2. 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.

3. 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

4. I would use %lf in the scanf. I don't know what %le does.

5. 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

6. 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.

7. 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));
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;
}```

8. 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.

9. 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?

10. 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);
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

11. 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);
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. 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

13. 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.

14. Thank you so much! It works now!!