Counting sort in C

Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
3
down vote
favorite
EDIT: I have posted a follow-up to this question.
I have implemented counting sort in C. This program takes its input as integers from command line arguments, sorts the integers with counting sort, then outputs the sorted array.
This is my first attempt at implementing this and I would really like to see what I could do better in this code.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int max(int* arr, int len)
int out = arr[0];
for (int i = 0; i < len; i++)
if (arr[i] > out)
out = arr[i];
return out;
void sort(int** in, int** out, size_t length)
int* inputs = *in;
int* outputs = *out;
// this is the size of the array of counts
int greatest = max(inputs, length); // find the greatest number in the array
// allocate the array of counts
int* counts = calloc(greatest + 1, sizeof(int));
// count numbers in input array
for (int i = 0; i < length; i++)
counts[inputs[i]]++;
int counter = 0; // keep track of where we are in output array
// loop through all the counts
for (int i = 0; i < (greatest + 1); i++) // for every count in array
for (int j = 0; j < counts[i]; j++) // loop that many times
outputs[counter++] = i; // add the integer being counted to the output array
free(counts);
int main(int argc, char** argv)
int *inputs, *outputs;
size_t length = argc - 1; // number of integers to sort
inputs = malloc(sizeof(int) * (argc - 1));
outputs = malloc(sizeof(int) * (argc - 1));
for (int i = 1; i < argc; i++)
inputs[i - 1] = atoi(argv[i]); // assign arguments to array
sort(&inputs, &outputs, length);
for (size_t i = 0; i < (length); i++)
printf("%d ", outputs[i]); // print space separated sorted numbers
printf("n");
free(inputs);
free(outputs);
return 0;
c sorting
add a comment |Â
up vote
3
down vote
favorite
EDIT: I have posted a follow-up to this question.
I have implemented counting sort in C. This program takes its input as integers from command line arguments, sorts the integers with counting sort, then outputs the sorted array.
This is my first attempt at implementing this and I would really like to see what I could do better in this code.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int max(int* arr, int len)
int out = arr[0];
for (int i = 0; i < len; i++)
if (arr[i] > out)
out = arr[i];
return out;
void sort(int** in, int** out, size_t length)
int* inputs = *in;
int* outputs = *out;
// this is the size of the array of counts
int greatest = max(inputs, length); // find the greatest number in the array
// allocate the array of counts
int* counts = calloc(greatest + 1, sizeof(int));
// count numbers in input array
for (int i = 0; i < length; i++)
counts[inputs[i]]++;
int counter = 0; // keep track of where we are in output array
// loop through all the counts
for (int i = 0; i < (greatest + 1); i++) // for every count in array
for (int j = 0; j < counts[i]; j++) // loop that many times
outputs[counter++] = i; // add the integer being counted to the output array
free(counts);
int main(int argc, char** argv)
int *inputs, *outputs;
size_t length = argc - 1; // number of integers to sort
inputs = malloc(sizeof(int) * (argc - 1));
outputs = malloc(sizeof(int) * (argc - 1));
for (int i = 1; i < argc; i++)
inputs[i - 1] = atoi(argv[i]); // assign arguments to array
sort(&inputs, &outputs, length);
for (size_t i = 0; i < (length); i++)
printf("%d ", outputs[i]); // print space separated sorted numbers
printf("n");
free(inputs);
free(outputs);
return 0;
c sorting
add a comment |Â
up vote
3
down vote
favorite
up vote
3
down vote
favorite
EDIT: I have posted a follow-up to this question.
I have implemented counting sort in C. This program takes its input as integers from command line arguments, sorts the integers with counting sort, then outputs the sorted array.
This is my first attempt at implementing this and I would really like to see what I could do better in this code.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int max(int* arr, int len)
int out = arr[0];
for (int i = 0; i < len; i++)
if (arr[i] > out)
out = arr[i];
return out;
void sort(int** in, int** out, size_t length)
int* inputs = *in;
int* outputs = *out;
// this is the size of the array of counts
int greatest = max(inputs, length); // find the greatest number in the array
// allocate the array of counts
int* counts = calloc(greatest + 1, sizeof(int));
// count numbers in input array
for (int i = 0; i < length; i++)
counts[inputs[i]]++;
int counter = 0; // keep track of where we are in output array
// loop through all the counts
for (int i = 0; i < (greatest + 1); i++) // for every count in array
for (int j = 0; j < counts[i]; j++) // loop that many times
outputs[counter++] = i; // add the integer being counted to the output array
free(counts);
int main(int argc, char** argv)
int *inputs, *outputs;
size_t length = argc - 1; // number of integers to sort
inputs = malloc(sizeof(int) * (argc - 1));
outputs = malloc(sizeof(int) * (argc - 1));
for (int i = 1; i < argc; i++)
inputs[i - 1] = atoi(argv[i]); // assign arguments to array
sort(&inputs, &outputs, length);
for (size_t i = 0; i < (length); i++)
printf("%d ", outputs[i]); // print space separated sorted numbers
printf("n");
free(inputs);
free(outputs);
return 0;
c sorting
EDIT: I have posted a follow-up to this question.
I have implemented counting sort in C. This program takes its input as integers from command line arguments, sorts the integers with counting sort, then outputs the sorted array.
This is my first attempt at implementing this and I would really like to see what I could do better in this code.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int max(int* arr, int len)
int out = arr[0];
for (int i = 0; i < len; i++)
if (arr[i] > out)
out = arr[i];
return out;
void sort(int** in, int** out, size_t length)
int* inputs = *in;
int* outputs = *out;
// this is the size of the array of counts
int greatest = max(inputs, length); // find the greatest number in the array
// allocate the array of counts
int* counts = calloc(greatest + 1, sizeof(int));
// count numbers in input array
for (int i = 0; i < length; i++)
counts[inputs[i]]++;
int counter = 0; // keep track of where we are in output array
// loop through all the counts
for (int i = 0; i < (greatest + 1); i++) // for every count in array
for (int j = 0; j < counts[i]; j++) // loop that many times
outputs[counter++] = i; // add the integer being counted to the output array
free(counts);
int main(int argc, char** argv)
int *inputs, *outputs;
size_t length = argc - 1; // number of integers to sort
inputs = malloc(sizeof(int) * (argc - 1));
outputs = malloc(sizeof(int) * (argc - 1));
for (int i = 1; i < argc; i++)
inputs[i - 1] = atoi(argv[i]); // assign arguments to array
sort(&inputs, &outputs, length);
for (size_t i = 0; i < (length); i++)
printf("%d ", outputs[i]); // print space separated sorted numbers
printf("n");
free(inputs);
free(outputs);
return 0;
c sorting
edited Jul 19 at 6:44
asked Jul 19 at 1:21
Dmitry Kudriavtsev
19811
19811
add a comment |Â
add a comment |Â
2 Answers
2
active
oldest
votes
up vote
4
down vote
accepted
Why do you pass in and out to sort as int **? You only dereference them to get the underlying pointer. Just pass in the pointers (rather than the address of the pointers) and take the parameters as int *inputs and int *outputs.
You don't check any of your memory allocations for errors.
You do free up the memory you allocate, which is good.
You don't validate your input values at all. If one of the numbers is negative Bad Things will happen when you clobber memory outside of what you've allocated.
The test i < (greatest + 1) can be restated as i <= greatest.
If I run the program with no parameters, you run into Undefined Behavior in your max function with arr[0].
When allocating space for inputs and outputs in main, you use (argc - 1). You've already computed this and stored it in length, which you use elsewhere. You should use this length value when allocating memory for your arrays.
I've revised my program to take care of most of these issues, where can I post the revised version?
â Dmitry Kudriavtsev
Jul 19 at 4:27
1
@DmitryKudriavtsev you can ask another question and link back to this topic. See codereview.meta.stackexchange.com/questions/1763/⦠for more information.
â Zeta
Jul 19 at 5:51
add a comment |Â
up vote
3
down vote
This is quite good so most of these comments are niggles / coding style. But...
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
Put #includes in sorted order. If you have a lot of them, it makes it easier to find a header or spot duplicates, and it can help avoid manual merges in a version control system
int max(int* arr, int len)
I'd avoid that name. I've come across more than one C implementation that provides a
maxmacro, causing great confusionint out = arr[0];
for (int i = 0; i < len; i++)That could be
for (int i = 1;- the check below can never succeed for i = 0Please don't omit the braces. People think that the compiler takes account of indenting. It doesn't. And this frequently leads to errors in maintenance (ref the goto fail bug).
if (arr[i] > out)
out = arr[i];
return out;
void sort(int** in, int** out, size_t length)
int* inputs = *in;
int* outputs = *out;Why pass a pointer to a pointer then immediately dereference it
in should be a pointer to const, as you aren't altering it. (
int const *)// this is the size of the array of counts
int greatest = max(inputs, length); // find the greatest number in the array
// allocate the array of counts
int* counts = calloc(greatest + 1, sizeof(int));unlike the other poster, I think
callocis appropriate here as you want zeroised memory andmallocis appropriate in the other places as you initialise them later.You should check if you actually got memory allocated here
// count numbers in input array
for (int i = 0; i < length; i++)
counts[inputs[i]]++;
int counter = 0; // keep track of where we are in output array
// loop through all the counts
for (int i = 0; i < (greatest + 1); i++) // for every count in array
for (int j = 0; j < counts[i]; j++) // loop that many times
outputs[counter++] = i; // add the integer being counted to the output arraypersonally I'd avoid using auto-increments as part of an expression and make that two statements. I doubt the compiler would produce worse code, and it saves you having to work out whether the increment is done before or after the value is accessed.
free(counts);
int main(int argc, char** argv)
int *inputs, *outputs;
size_t length = argc - 1; // number of integers to sortdeclare variables as close as possible to where you use them. These next two lines should be declarations
You don't check it the malloc was succesful
if
argcis 1, thenlengthis 0, and you'll attempt to allocate a very large amount of memory hereinputs = malloc(sizeof(int) * (argc - 1));
outputs = malloc(sizeof(int) * (argc - 1));
for (int i = 1; i < argc; i++)
inputs[i - 1] = atoi(argv[i]); // assign arguments to array
sort(&inputs, &outputs, length);
for (size_t i = 0; i < (length); i++)
printf("%d ", outputs[i]); // print space separated sorted numbers
printf("n");arguably printf is overkill. You could use
putchar('n')herefree(inputs);
free(outputs);
return 0;Well done for the last 3 lines (freeing up the memory and returning 0)! I've frequently seen one or both of those steps omitted.
It's perfectly legitimate to omitreturn 0;at the end ofmain()(but no other non-voidfunction).
â Toby Speight
Jul 19 at 8:06
I thought that was only C++?
â Tom Tanner
Jul 19 at 10:01
Both C and C++.
â Toby Speight
Jul 19 at 10:06
ah, thanks. i'll remember that
â Tom Tanner
Jul 19 at 10:07
add a comment |Â
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
4
down vote
accepted
Why do you pass in and out to sort as int **? You only dereference them to get the underlying pointer. Just pass in the pointers (rather than the address of the pointers) and take the parameters as int *inputs and int *outputs.
You don't check any of your memory allocations for errors.
You do free up the memory you allocate, which is good.
You don't validate your input values at all. If one of the numbers is negative Bad Things will happen when you clobber memory outside of what you've allocated.
The test i < (greatest + 1) can be restated as i <= greatest.
If I run the program with no parameters, you run into Undefined Behavior in your max function with arr[0].
When allocating space for inputs and outputs in main, you use (argc - 1). You've already computed this and stored it in length, which you use elsewhere. You should use this length value when allocating memory for your arrays.
I've revised my program to take care of most of these issues, where can I post the revised version?
â Dmitry Kudriavtsev
Jul 19 at 4:27
1
@DmitryKudriavtsev you can ask another question and link back to this topic. See codereview.meta.stackexchange.com/questions/1763/⦠for more information.
â Zeta
Jul 19 at 5:51
add a comment |Â
up vote
4
down vote
accepted
Why do you pass in and out to sort as int **? You only dereference them to get the underlying pointer. Just pass in the pointers (rather than the address of the pointers) and take the parameters as int *inputs and int *outputs.
You don't check any of your memory allocations for errors.
You do free up the memory you allocate, which is good.
You don't validate your input values at all. If one of the numbers is negative Bad Things will happen when you clobber memory outside of what you've allocated.
The test i < (greatest + 1) can be restated as i <= greatest.
If I run the program with no parameters, you run into Undefined Behavior in your max function with arr[0].
When allocating space for inputs and outputs in main, you use (argc - 1). You've already computed this and stored it in length, which you use elsewhere. You should use this length value when allocating memory for your arrays.
I've revised my program to take care of most of these issues, where can I post the revised version?
â Dmitry Kudriavtsev
Jul 19 at 4:27
1
@DmitryKudriavtsev you can ask another question and link back to this topic. See codereview.meta.stackexchange.com/questions/1763/⦠for more information.
â Zeta
Jul 19 at 5:51
add a comment |Â
up vote
4
down vote
accepted
up vote
4
down vote
accepted
Why do you pass in and out to sort as int **? You only dereference them to get the underlying pointer. Just pass in the pointers (rather than the address of the pointers) and take the parameters as int *inputs and int *outputs.
You don't check any of your memory allocations for errors.
You do free up the memory you allocate, which is good.
You don't validate your input values at all. If one of the numbers is negative Bad Things will happen when you clobber memory outside of what you've allocated.
The test i < (greatest + 1) can be restated as i <= greatest.
If I run the program with no parameters, you run into Undefined Behavior in your max function with arr[0].
When allocating space for inputs and outputs in main, you use (argc - 1). You've already computed this and stored it in length, which you use elsewhere. You should use this length value when allocating memory for your arrays.
Why do you pass in and out to sort as int **? You only dereference them to get the underlying pointer. Just pass in the pointers (rather than the address of the pointers) and take the parameters as int *inputs and int *outputs.
You don't check any of your memory allocations for errors.
You do free up the memory you allocate, which is good.
You don't validate your input values at all. If one of the numbers is negative Bad Things will happen when you clobber memory outside of what you've allocated.
The test i < (greatest + 1) can be restated as i <= greatest.
If I run the program with no parameters, you run into Undefined Behavior in your max function with arr[0].
When allocating space for inputs and outputs in main, you use (argc - 1). You've already computed this and stored it in length, which you use elsewhere. You should use this length value when allocating memory for your arrays.
edited Jul 19 at 16:49
answered Jul 19 at 3:51
1201ProgramAlarm
2,4752618
2,4752618
I've revised my program to take care of most of these issues, where can I post the revised version?
â Dmitry Kudriavtsev
Jul 19 at 4:27
1
@DmitryKudriavtsev you can ask another question and link back to this topic. See codereview.meta.stackexchange.com/questions/1763/⦠for more information.
â Zeta
Jul 19 at 5:51
add a comment |Â
I've revised my program to take care of most of these issues, where can I post the revised version?
â Dmitry Kudriavtsev
Jul 19 at 4:27
1
@DmitryKudriavtsev you can ask another question and link back to this topic. See codereview.meta.stackexchange.com/questions/1763/⦠for more information.
â Zeta
Jul 19 at 5:51
I've revised my program to take care of most of these issues, where can I post the revised version?
â Dmitry Kudriavtsev
Jul 19 at 4:27
I've revised my program to take care of most of these issues, where can I post the revised version?
â Dmitry Kudriavtsev
Jul 19 at 4:27
1
1
@DmitryKudriavtsev you can ask another question and link back to this topic. See codereview.meta.stackexchange.com/questions/1763/⦠for more information.
â Zeta
Jul 19 at 5:51
@DmitryKudriavtsev you can ask another question and link back to this topic. See codereview.meta.stackexchange.com/questions/1763/⦠for more information.
â Zeta
Jul 19 at 5:51
add a comment |Â
up vote
3
down vote
This is quite good so most of these comments are niggles / coding style. But...
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
Put #includes in sorted order. If you have a lot of them, it makes it easier to find a header or spot duplicates, and it can help avoid manual merges in a version control system
int max(int* arr, int len)
I'd avoid that name. I've come across more than one C implementation that provides a
maxmacro, causing great confusionint out = arr[0];
for (int i = 0; i < len; i++)That could be
for (int i = 1;- the check below can never succeed for i = 0Please don't omit the braces. People think that the compiler takes account of indenting. It doesn't. And this frequently leads to errors in maintenance (ref the goto fail bug).
if (arr[i] > out)
out = arr[i];
return out;
void sort(int** in, int** out, size_t length)
int* inputs = *in;
int* outputs = *out;Why pass a pointer to a pointer then immediately dereference it
in should be a pointer to const, as you aren't altering it. (
int const *)// this is the size of the array of counts
int greatest = max(inputs, length); // find the greatest number in the array
// allocate the array of counts
int* counts = calloc(greatest + 1, sizeof(int));unlike the other poster, I think
callocis appropriate here as you want zeroised memory andmallocis appropriate in the other places as you initialise them later.You should check if you actually got memory allocated here
// count numbers in input array
for (int i = 0; i < length; i++)
counts[inputs[i]]++;
int counter = 0; // keep track of where we are in output array
// loop through all the counts
for (int i = 0; i < (greatest + 1); i++) // for every count in array
for (int j = 0; j < counts[i]; j++) // loop that many times
outputs[counter++] = i; // add the integer being counted to the output arraypersonally I'd avoid using auto-increments as part of an expression and make that two statements. I doubt the compiler would produce worse code, and it saves you having to work out whether the increment is done before or after the value is accessed.
free(counts);
int main(int argc, char** argv)
int *inputs, *outputs;
size_t length = argc - 1; // number of integers to sortdeclare variables as close as possible to where you use them. These next two lines should be declarations
You don't check it the malloc was succesful
if
argcis 1, thenlengthis 0, and you'll attempt to allocate a very large amount of memory hereinputs = malloc(sizeof(int) * (argc - 1));
outputs = malloc(sizeof(int) * (argc - 1));
for (int i = 1; i < argc; i++)
inputs[i - 1] = atoi(argv[i]); // assign arguments to array
sort(&inputs, &outputs, length);
for (size_t i = 0; i < (length); i++)
printf("%d ", outputs[i]); // print space separated sorted numbers
printf("n");arguably printf is overkill. You could use
putchar('n')herefree(inputs);
free(outputs);
return 0;Well done for the last 3 lines (freeing up the memory and returning 0)! I've frequently seen one or both of those steps omitted.
It's perfectly legitimate to omitreturn 0;at the end ofmain()(but no other non-voidfunction).
â Toby Speight
Jul 19 at 8:06
I thought that was only C++?
â Tom Tanner
Jul 19 at 10:01
Both C and C++.
â Toby Speight
Jul 19 at 10:06
ah, thanks. i'll remember that
â Tom Tanner
Jul 19 at 10:07
add a comment |Â
up vote
3
down vote
This is quite good so most of these comments are niggles / coding style. But...
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
Put #includes in sorted order. If you have a lot of them, it makes it easier to find a header or spot duplicates, and it can help avoid manual merges in a version control system
int max(int* arr, int len)
I'd avoid that name. I've come across more than one C implementation that provides a
maxmacro, causing great confusionint out = arr[0];
for (int i = 0; i < len; i++)That could be
for (int i = 1;- the check below can never succeed for i = 0Please don't omit the braces. People think that the compiler takes account of indenting. It doesn't. And this frequently leads to errors in maintenance (ref the goto fail bug).
if (arr[i] > out)
out = arr[i];
return out;
void sort(int** in, int** out, size_t length)
int* inputs = *in;
int* outputs = *out;Why pass a pointer to a pointer then immediately dereference it
in should be a pointer to const, as you aren't altering it. (
int const *)// this is the size of the array of counts
int greatest = max(inputs, length); // find the greatest number in the array
// allocate the array of counts
int* counts = calloc(greatest + 1, sizeof(int));unlike the other poster, I think
callocis appropriate here as you want zeroised memory andmallocis appropriate in the other places as you initialise them later.You should check if you actually got memory allocated here
// count numbers in input array
for (int i = 0; i < length; i++)
counts[inputs[i]]++;
int counter = 0; // keep track of where we are in output array
// loop through all the counts
for (int i = 0; i < (greatest + 1); i++) // for every count in array
for (int j = 0; j < counts[i]; j++) // loop that many times
outputs[counter++] = i; // add the integer being counted to the output arraypersonally I'd avoid using auto-increments as part of an expression and make that two statements. I doubt the compiler would produce worse code, and it saves you having to work out whether the increment is done before or after the value is accessed.
free(counts);
int main(int argc, char** argv)
int *inputs, *outputs;
size_t length = argc - 1; // number of integers to sortdeclare variables as close as possible to where you use them. These next two lines should be declarations
You don't check it the malloc was succesful
if
argcis 1, thenlengthis 0, and you'll attempt to allocate a very large amount of memory hereinputs = malloc(sizeof(int) * (argc - 1));
outputs = malloc(sizeof(int) * (argc - 1));
for (int i = 1; i < argc; i++)
inputs[i - 1] = atoi(argv[i]); // assign arguments to array
sort(&inputs, &outputs, length);
for (size_t i = 0; i < (length); i++)
printf("%d ", outputs[i]); // print space separated sorted numbers
printf("n");arguably printf is overkill. You could use
putchar('n')herefree(inputs);
free(outputs);
return 0;Well done for the last 3 lines (freeing up the memory and returning 0)! I've frequently seen one or both of those steps omitted.
It's perfectly legitimate to omitreturn 0;at the end ofmain()(but no other non-voidfunction).
â Toby Speight
Jul 19 at 8:06
I thought that was only C++?
â Tom Tanner
Jul 19 at 10:01
Both C and C++.
â Toby Speight
Jul 19 at 10:06
ah, thanks. i'll remember that
â Tom Tanner
Jul 19 at 10:07
add a comment |Â
up vote
3
down vote
up vote
3
down vote
This is quite good so most of these comments are niggles / coding style. But...
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
Put #includes in sorted order. If you have a lot of them, it makes it easier to find a header or spot duplicates, and it can help avoid manual merges in a version control system
int max(int* arr, int len)
I'd avoid that name. I've come across more than one C implementation that provides a
maxmacro, causing great confusionint out = arr[0];
for (int i = 0; i < len; i++)That could be
for (int i = 1;- the check below can never succeed for i = 0Please don't omit the braces. People think that the compiler takes account of indenting. It doesn't. And this frequently leads to errors in maintenance (ref the goto fail bug).
if (arr[i] > out)
out = arr[i];
return out;
void sort(int** in, int** out, size_t length)
int* inputs = *in;
int* outputs = *out;Why pass a pointer to a pointer then immediately dereference it
in should be a pointer to const, as you aren't altering it. (
int const *)// this is the size of the array of counts
int greatest = max(inputs, length); // find the greatest number in the array
// allocate the array of counts
int* counts = calloc(greatest + 1, sizeof(int));unlike the other poster, I think
callocis appropriate here as you want zeroised memory andmallocis appropriate in the other places as you initialise them later.You should check if you actually got memory allocated here
// count numbers in input array
for (int i = 0; i < length; i++)
counts[inputs[i]]++;
int counter = 0; // keep track of where we are in output array
// loop through all the counts
for (int i = 0; i < (greatest + 1); i++) // for every count in array
for (int j = 0; j < counts[i]; j++) // loop that many times
outputs[counter++] = i; // add the integer being counted to the output arraypersonally I'd avoid using auto-increments as part of an expression and make that two statements. I doubt the compiler would produce worse code, and it saves you having to work out whether the increment is done before or after the value is accessed.
free(counts);
int main(int argc, char** argv)
int *inputs, *outputs;
size_t length = argc - 1; // number of integers to sortdeclare variables as close as possible to where you use them. These next two lines should be declarations
You don't check it the malloc was succesful
if
argcis 1, thenlengthis 0, and you'll attempt to allocate a very large amount of memory hereinputs = malloc(sizeof(int) * (argc - 1));
outputs = malloc(sizeof(int) * (argc - 1));
for (int i = 1; i < argc; i++)
inputs[i - 1] = atoi(argv[i]); // assign arguments to array
sort(&inputs, &outputs, length);
for (size_t i = 0; i < (length); i++)
printf("%d ", outputs[i]); // print space separated sorted numbers
printf("n");arguably printf is overkill. You could use
putchar('n')herefree(inputs);
free(outputs);
return 0;Well done for the last 3 lines (freeing up the memory and returning 0)! I've frequently seen one or both of those steps omitted.
This is quite good so most of these comments are niggles / coding style. But...
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
Put #includes in sorted order. If you have a lot of them, it makes it easier to find a header or spot duplicates, and it can help avoid manual merges in a version control system
int max(int* arr, int len)
I'd avoid that name. I've come across more than one C implementation that provides a
maxmacro, causing great confusionint out = arr[0];
for (int i = 0; i < len; i++)That could be
for (int i = 1;- the check below can never succeed for i = 0Please don't omit the braces. People think that the compiler takes account of indenting. It doesn't. And this frequently leads to errors in maintenance (ref the goto fail bug).
if (arr[i] > out)
out = arr[i];
return out;
void sort(int** in, int** out, size_t length)
int* inputs = *in;
int* outputs = *out;Why pass a pointer to a pointer then immediately dereference it
in should be a pointer to const, as you aren't altering it. (
int const *)// this is the size of the array of counts
int greatest = max(inputs, length); // find the greatest number in the array
// allocate the array of counts
int* counts = calloc(greatest + 1, sizeof(int));unlike the other poster, I think
callocis appropriate here as you want zeroised memory andmallocis appropriate in the other places as you initialise them later.You should check if you actually got memory allocated here
// count numbers in input array
for (int i = 0; i < length; i++)
counts[inputs[i]]++;
int counter = 0; // keep track of where we are in output array
// loop through all the counts
for (int i = 0; i < (greatest + 1); i++) // for every count in array
for (int j = 0; j < counts[i]; j++) // loop that many times
outputs[counter++] = i; // add the integer being counted to the output arraypersonally I'd avoid using auto-increments as part of an expression and make that two statements. I doubt the compiler would produce worse code, and it saves you having to work out whether the increment is done before or after the value is accessed.
free(counts);
int main(int argc, char** argv)
int *inputs, *outputs;
size_t length = argc - 1; // number of integers to sortdeclare variables as close as possible to where you use them. These next two lines should be declarations
You don't check it the malloc was succesful
if
argcis 1, thenlengthis 0, and you'll attempt to allocate a very large amount of memory hereinputs = malloc(sizeof(int) * (argc - 1));
outputs = malloc(sizeof(int) * (argc - 1));
for (int i = 1; i < argc; i++)
inputs[i - 1] = atoi(argv[i]); // assign arguments to array
sort(&inputs, &outputs, length);
for (size_t i = 0; i < (length); i++)
printf("%d ", outputs[i]); // print space separated sorted numbers
printf("n");arguably printf is overkill. You could use
putchar('n')herefree(inputs);
free(outputs);
return 0;Well done for the last 3 lines (freeing up the memory and returning 0)! I've frequently seen one or both of those steps omitted.
answered Jul 19 at 7:36
Tom Tanner
41339
41339
It's perfectly legitimate to omitreturn 0;at the end ofmain()(but no other non-voidfunction).
â Toby Speight
Jul 19 at 8:06
I thought that was only C++?
â Tom Tanner
Jul 19 at 10:01
Both C and C++.
â Toby Speight
Jul 19 at 10:06
ah, thanks. i'll remember that
â Tom Tanner
Jul 19 at 10:07
add a comment |Â
It's perfectly legitimate to omitreturn 0;at the end ofmain()(but no other non-voidfunction).
â Toby Speight
Jul 19 at 8:06
I thought that was only C++?
â Tom Tanner
Jul 19 at 10:01
Both C and C++.
â Toby Speight
Jul 19 at 10:06
ah, thanks. i'll remember that
â Tom Tanner
Jul 19 at 10:07
It's perfectly legitimate to omit
return 0; at the end of main() (but no other non-void function).â Toby Speight
Jul 19 at 8:06
It's perfectly legitimate to omit
return 0; at the end of main() (but no other non-void function).â Toby Speight
Jul 19 at 8:06
I thought that was only C++?
â Tom Tanner
Jul 19 at 10:01
I thought that was only C++?
â Tom Tanner
Jul 19 at 10:01
Both C and C++.
â Toby Speight
Jul 19 at 10:06
Both C and C++.
â Toby Speight
Jul 19 at 10:06
ah, thanks. i'll remember that
â Tom Tanner
Jul 19 at 10:07
ah, thanks. i'll remember that
â Tom Tanner
Jul 19 at 10:07
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f199789%2fcounting-sort-in-c%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password