2

Hey guys (be forewarned that this question makes me feel n00b so I probably am),

I'm able to dynamically create an array and I'm able to use qsort effectively for a statically created array but am having trouble using qsort on a dynamically created one. I think I'm stumbling on my use of pointers.

struct my_struct {
    FILE *fp;
    int i;
};

So the array contains the above struct and I'd like to sort it by the int value.

Statically, I can do something like this:

struct my_struct array[4];

And sort:

qsort((void *) &array, sizeof(array) / sizeof(struct my_struct), sizeof(struct my_struct), *compare);

--

If I create the array thus:

struct my_struct* = malloc(sizeof(struct process) * 4);

Everything compiles and runs, however execution never goes into the compare function.

Any help would be greatly appreciated

1
  • I assume you mean struct my_struct *array = malloc(sizeof(*array) * 4);? Commented Sep 28, 2012 at 4:54

2 Answers 2

5

sizeof(array) is (sizeof(struct my_struct) * array_size) for constant-size array, but it's only pointer size for dynamic one. You have to calculate actual size (one you passed to malloc) yourself and put it into qsort call.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks ^_^ that was a fairly dumb move on my part
2

Your invocation of qsort only works by accident:

qsort((void *) &array, sizeof(array) / sizeof(struct my_struct), sizeof(struct my_struct), *compare);

The address of an array has the same value but a different type from the address of the zeroth element of the array. The cast to void * is also superfluous; and the dereference of the comparator function is also aconventional. Normally, that'd be written:

qsort(array, sizeof(array) / sizeof(array[0]), sizeof(struct my_struct), compare);

Or:

qsort(array, sizeof(array) / sizeof(array[0]), sizeof(array[0]), compare);

If you have a dynamically allocated structure:

size_t num_items = 4;
struct my_struct *dynarr = malloc(sizeof(struct my_struct) * num_items);

or:

struct my_struct *dynarr = malloc(sizeof(*dynarr) * num_items);

then you will be specifying the number of elements differently in the call to qsort, but the rest is essentially unchanged:

qsort(dynarr, num_items, sizeof(*dynarr), compare);

Note in particular that there is no & in front of dynarr, which is a simple pointer variable, for all it has a possibly misleading name.


Why your code went wrong

A guess, but a plausible guess. If you wrote:

qsort(&dynarr, sizeof(dynarr) / sizeof(dynarr[0]), sizeof(dynarr[0]), compare);

then sizeof(dynarr) is the size of a pointer (say 8 bytes in a 64-bit program), and sizeof(dynarr[0]) is 16 bytes, so the size (number of elements) that you tell qsort() to sort is 0 (because 8 / 16 == 0), so the comparator would never be called. If your program is compiled as a 32-bit program, the sizes are 4 bytes for the pointer and 8 for the structure, so the result is still 0.

Note that if instead you passed 4 or num_items as the size of the array, then you'd get a crash. The address of dynarr is the wrong address to pass to the function; you want to pass the address value that is held in dynarr, not the address at which dynarr itself is stored.

NB: You should show the qsort() that doesn't work so we don't have to guess what you've written.

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.