0

I have the following function that needs to return an array of pointers to a sorted list

int **list_elements_sorted(int *array, int n)
{
  if (n <= 0)
  {
    return NULL;
  }

  int **sorted_list = malloc(n * sizeof(int *));
  assert((sorted_list != NULL) && "Error! Memory allocation failed!");

  for (int i = 0; i < n; i++)
  {
    sorted_list[i] = &array[i];
  }

  qsort(sorted_list, n, sizeof(int *), comp_list_asc);

  return sorted_list;
}

And the comparator function

int comp_list_asc(const void *a, const void *b)
{
  int *A = *(int **)a;
  int *B = *(int **)b;

  return (A - B);
}

When I input an array E.G: 3 2 5 I'm getting the same output 3 2 5, what I'm doing wrong ?

void test_sorted_list_valid_3(void **state)
{
  int **output;

  int n = 3;
  int int_list[] = {3, 2, 5};
  int *int_list_sorted[] = {&int_list[1],
                            &int_list[0],
                            &int_list[2]};

  output = list_elements_sorted(int_list, n);

  assert_memory_equal(int_list_sorted, output, n);
  free(output);
}
6
  • 3 2 5 is not an array of pointers, it is an array of integers. And your sorted_list should be such Commented Sep 29, 2021 at 13:40
  • I suspect (A-B) will always give you a positive result due to pointers being unsigned (aka the void type). But I'am not sure... Commented Sep 29, 2021 at 13:43
  • @EugeneSh. sorted_list is an array of pointers pointing to the array integers, array is my input Commented Sep 29, 2021 at 13:47
  • 1
    Please show a minimal reproducible example Commented Sep 29, 2021 at 13:48
  • 1
    This does not make sense. You are expecting integers 3 2 5 to come out sorted (aren't you?), not their addresses. Commented Sep 29, 2021 at 13:49

2 Answers 2

5

You're subtracting pointers, instead of integers. The below change should work for you.

int comp_list_asc(const void *a, const void *b)
{
  int *A = *(int **)a;
  int *B = *(int **)b;

  return (*A - *B); // here's the change
}

As pointed out by @tstanisl, subtracting integers is prone to overflow/underflow errors. These can be addressed by changing the return statement like below.

return *A == *B ? 0 : *A < *B ? -1 : 1;
Sign up to request clarification or add additional context in comments.

2 Comments

it's sensitive to integer overflows, i.e. *A == INT_MAX and *B == INT_MIN
Is this really all it took to fix the problem? I don't get it ...
0

You need to dereference A and B before subtracting in comp_list_asc.

You also sort the wrong thing, int_list (which is not an array of int*), instead of int_list_sorted.

#include <stdio.h>
#include <stdlib.h>

int comp_list_asc(const void *a, const void *b) {
    int *A = *(int **)a;
    int *B = *(int **)b;

    return *A - *B;      // dereference
}

int main() {
    int int_list[] = {3, 2, 5};

    int *int_list_sorted[] = {&int_list[0],
                              &int_list[1],
                              &int_list[2]};

    int n = sizeof int_list_sorted / sizeof *int_list_sorted;

    // Sort the correct thing:

    qsort(int_list_sorted, n, sizeof(int *), comp_list_asc);

    // Print result to compare input and output:

    for(int i = 0; i < n; ++i) {
        printf("%d %d\n", int_list[i], *int_list_sorted[i]);
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.