Bucket Sort Seg Fault - c

I'm trying to implement a bucket sort using a resizable vector function that I made. The vector works fine, but I get a segmentation fault anytime I try to run my sort function. Can anyone help me remedy this?
Notes about code: K=# of buckets in this case 10. find_max and find_min do exactly what you'd expect. vector_int_construct initializes an array and vector_int_push_back pushes integers to the end of the array. vector_int_sort just calls on a merge_sort function I created that also works fine on its own.
typedef struct {
size_t size;
size_t maxsize;
int* array;
}
vector_int_t;
void bucket_sort( int* a, size_t size )
{
int min = find_min( a, size );
int max = find_max( a, size );
size_t range = (( max - min ) / K );
vector_int_t buckets[K];
for( size_t i = 0; i < K; i++ ) {
vector_int_construct( &buckets[i] );
for( size_t j = 0; j < range; j++ ) {
vector_int_push_back( &buckets[i], a[j] );
}
}
for( size_t i = 0; i < K; i++ ) {
vector_int_sort( &buckets[i] );
}
size_t cnt = 0;
while( cnt != size ) {
for( size_t i = 0; i < K; i++ ) {
for( size_t j = 0; j < vector_int_size( &buckets[i] ); j++ ) {
a[cnt] = buckets[i].array[j];
cnt++;
}
}
}
}
int main()
{
size_t size = 4;
int a[] = { 19, 95, 4, 23 };
// Print out array before
printf( "Before sorting: " );
ece2400_print_array( a, size );
// Call sort
bucket_sort( a, size );
// Print out array after
printf( "After sorting: " );
ece2400_print_array( a, size );
return 0;
}

Related

C: copying array in function by using pointers gave unusual result, why did it half work?

So I don't want to make a function for every data type, I would like to be able to just use pointers to fix the problem. Tried the idea with a function for copying an array. I didn't get the result i expected or wanted, even if it had just gone entirely wrong with the new_arr not changing at all i would be ok this isn't it. but it gave me hope.
void *copy_array(const void *arr[], const void *new_arr[], size_t arr_len, size_t type_size) {
for (int i = 0; i < arr_len ; ++i) {
*(new_arr + (i * type_size)) = *(arr + (i * type_size));
}
}
void print_int_array(int * array, int length) {
for (int i = 0; i < length; ++i) {
printf("\nelement %d = %d", i, array[i]);
}
}
int main() {
int arr[ARRAY_LENGTH] = {12, 3,4};
int new_arr[ARRAY_LENGTH] = {0, 0, 0};
print_int_array(arr, ARRAY_LENGTH);
print_int_array(new_arr, ARRAY_LENGTH);
copy_array(&arr, &new_arr, ARRAY_LENGTH, sizeof(new_arr[0]));
print_int_array(arr, ARRAY_LENGTH);
print_int_array(new_arr, ARRAY_LENGTH);
return 0;
}
Console returns this for some reason, it gets the 12 and the 3 by why not the 4?
element 0 = 12
element 1 = 3
element 2 = 4
element 0 = 0
element 1 = 0
element 2 = 0
element 0 = 12
element 1 = 3
element 2 = 4
element 0 = 12
element 1 = 3
element 2 = 0
You declared a function
void *copy_array(const void *arr[], const void *new_arr[], size_t arr_len, size_t type_size) {
where the both first parameters have the qualifier const. So the function declaration is incorrect.
Instead it would be better to declare the first parameter of the function print_int_array with the qualifier const and the second parameter as having the type size_t
void print_int_array( const int * array, size_t length) {
On the other hand, the expressions
*(new_arr + (i * type_size))
and
*(arr + (i * type_size))
have pointer types. Their sizes can be greater than the size of an object of the type int. For example sizeof( void * ) can be equal to 8 while sizeof( int ) can be equal to 4.
Thus the function can invoke undefined behavior.
Apart from that the function has a non-void return type but returns nothing.
Also there is no great sense to call the function passing pointers to arrays like
copy_array(&arr, &new_arr, ARRAY_LENGTH, sizeof(new_arr[0]));
where each expression has the type int( * )[3].
The function can be defined the following way as shown in the demonstration program below.
#include <stdio.h>
#include <string.h>
void copy_array( void *new_arr, const void *arr, size_t arr_len, size_t type_size )
{
for (size_t i = 0; i < arr_len; i++)
{
memcpy( new_arr, arr, type_size );
new_arr = ( char * )new_arr + type_size;
arr = ( const char * )arr + type_size;
}
}
int main( void )
{
enum { ARRAY_LENGTH = 3 };
int arr[ARRAY_LENGTH] = { 12, 3,4 };
int new_arr[ARRAY_LENGTH] = { 0, 0, 0 };
printf( "arr : " );
for (size_t i = 0; i < ARRAY_LENGTH; i++)
{
printf( "%d ", arr[i] );
}
putchar( '\n' );
printf( "new_arr: " );
for (size_t i = 0; i < ARRAY_LENGTH; i++)
{
printf( "%d ", new_arr[i] );
}
putchar( '\n' );
putchar( '\n' );
copy_array( new_arr, arr, ARRAY_LENGTH, sizeof( int ) );
printf( "arr : " );
for (size_t i = 0; i < ARRAY_LENGTH; i++)
{
printf( "%d ", arr[i] );
}
putchar( '\n' );
printf( "new_arr: " );
for (size_t i = 0; i < ARRAY_LENGTH; i++)
{
printf( "%d ", new_arr[i] );
}
putchar( '\n' );
}
The program output is
arr : 12 3 4
new_arr: 0 0 0
arr : 12 3 4
new_arr: 12 3 4
So this is what i wanted to do which is basicly memcpy. The arrays get converted to char arrays which is only 1 byte, so every byte gets copied from the size of the original array.
void copy_array(void *arr, void *new_arr, size_t arr_size) {
char *char_new_arr = (char *) new_arr;
char *char_arr = (char *) arr;
for (int i = 0; i < arr_size; ++i) {
char_new_arr[i] = char_arr[i];
}
}

main.c:36:9: error: array size missing in ‘num’ int num[]; Why am I getting error for array size although i have given array size in code?

#include <stdio.h>
int removeduplicates(int arr[],int n){
int j=0;
int temp[15];
if(n==0 || n==1){
return n;
}
for(int i=0;i<n-1;i++){
if(arr[i]!=arr[i+1]){
temp[j++]=arr[i];
}
temp[j++]=arr[n-1];
}
for(int i=0;i<j;i++){
arr[i]=temp[i];
}
return j;
}
int main(){
int n;
int num[];
num[]= {1,2,3,3,4,4,5,5,5};
n= sizeof(num)/sizeof(num[0]);
n=removeduplicates(num,n);
printf("%d",n);
return 0;
}
Here in this question I was writing a code to remove duplicates from a sorted array. But I am getting the following error although I defined the array size and although I provided the array size.
main.c:36:9: error: array size missing in ‘num’
int num[];
^~~
main.c:37:9: error: expected expression before ‘]’ token
num[]= {1,2,3,3,4,4,5,5,5};
This code snippet
int num[];
num[]= {1,2,3,3,4,4,5,5,5};
is syntactically incorrect.
Instead write
int num[] = {1,2,3,3,4,4,5,5,5};
Also within the function this declaration with the magic number 15
int temp[15];
and this statement
temp[j++]=arr[n-1];
in the substatement of this for loop
for(int i=0;i<n-1;i++){
if(arr[i]!=arr[i+1]){
temp[j++]=arr[i];
}
temp[j++]=arr[n-1];
}
do not make a sense.
To remove duplicates there is no need to define an auxiliary array.
The function can be written for example the following way as shwon in the demonstrative program below.
#include <stdio.h>
size_t removeduplicates( int arr[], size_t n )
{
size_t m = 0;
for ( size_t i = 0; i != n; )
{
if ( m != i )
{
arr[m] = arr[i];
}
++m;
while ( ( ++i != n && arr[i] == arr[i-1] ) );
}
return m;
}
int main(void)
{
int num[]= { 1, 2, 3, 3, 4, 4, 5, 5, 5 };
const size_t N = sizeof( num ) / sizeof( *num );
for ( size_t i = 0; i != N; i++ )
{
printf( "%d ", num[i] );
}
putchar( '\n' );
size_t m = removeduplicates( num, N );
for ( size_t i = 0; i != m; i++ )
{
printf( "%d ", num[i] );
}
putchar( '\n' );
return 0;
}
The program output is
1 2 3 3 4 4 5 5 5
1 2 3 4 5

To perform insert operation in a sorted array

What is wrong with this code and where is the problem?
I ran this code many times but it's showing that the code is running but I am not getting any output.
Can you tell me where is the mistake?
#include <stdio.h>
int print_arr(int *arr, int n)
{ for(int i=0; i<=n; i++)
{
printf("%d ",arr[i]);
}
return 0;
}
int insert_ele(int *arr_a, int *arr_b, int n, int Key)
{
int i,j;
for(i=0, j=0; i<n; i++, j++)
{
if(arr_a[i]>Key)
{
arr_b[j] = Key;
arr_b[j+1] = arr_a[i];
j++;
}
else
{
arr_b[j] = arr_a[i];
}
}
return 0;
}
int main()
{
//code
int arr_a[] = {12, 16, 20, 40, 50, 70};
int arr_b[10];
int Key = 26;
int n = sizeof(arr_a)/sizeof(arr_a[0]);
int indx = insert_ele(arr_a, arr_b, n, Key);
print_arr(arr, n);
return 0;
}
For starters there is a typo in this statement
print_arr(arr, n);
It seems you mean
print_arr( arr_b, n + 1 );
The return type int of the function print_arr does not make a sense and is useless.
The first parameter of the function should have the qualifier const because the passed array is not being changed within the function.
The second parameter should have the type size_t.
This for loop
for(int i=0; i<=n; i++)
can invoke undefined behavior if the user of the function will pass the number of elements in the array in the second parameter n because in this case there will be an attempt to access memory beyond the array.
Again the return type int of the function insert_ele does not make a sense and is useless.
The first parameter should have the qualifier const because the source array is not being changed within the function. The parameter n should have the type size_t.
The function has a logical error.
Let's assume that the value of the variable Key is less than values of all elements of the array arr_a.
In this case the index j will be incremented twice and as a result you will have
b[0] = Key; b[2] = Key; b[4] = Key; and so on.
The logic of the function will be much clear if to split the for loop in two for loops.
The program can look the following way.
#include <stdio.h>
size_t insert_ele( const int *a, size_t n, int *b, int key )
{
size_t i = 0;
for ( ; i < n && !( key < a[i] ); i++ )
{
b[i] = a[i];
}
b[i] = key;
for ( ; i < n; i++ )
{
b[i+1] = a[i];
}
return i;
}
FILE * print_arr( const int *a, size_t n, FILE *fp )
{
for ( size_t i = 0; i < n; i++)
{
fprintf( fp, "%d ", a[i] );
}
return fp;
}
int main(void)
{
int a[] = { 12, 16, 20, 40, 50, 70 };
const size_t N = sizeof( a ) / sizeof( *a );
int b[10];
int key = 26;
size_t m = insert_ele( a, N, b, key );
fputc( '\n', print_arr( b, m, stdout ) );
return 0;
}
The program output is
12 16 20 26 40 50

How to count instance of items from an array in C?

I apologize if this question seems too vague, but I am a complete beginner and I am stuck on how to count instances of numbers from an array.
I have a function called create_hist() which has three inputs: an input double array for which the numbers range from 0 to 16, an input integer which indicates how many elements are in the array, and an output integer array of size 17. The goal is to count how many of each numbers are in the first array, and then assign that number to the correct index of the output array i.e:
If the input array contains {0,1,1,2,3,4,4} then the count will be 7, and the output array should be {1,2,1,1,2,0,0,0,0,0,0,0,0,0,0,0,0}.
I am very new to C programming and I don't know where to start. My thoughts were that I could iterate through each element in the input array, and if the element was equal to zero, then add 1 to the first index of the output array and so on. I know this is wrong but I don't know another way. Could someone please guide me on how I could begin this? My first attempt is below.
int create_hist( double input_array[], int count, int hist[17] ) {
for ( int i = 0; i < count; i++ ) {
if ( input_array[i] == 0; ) {
// then add 1 to hist[0]
}
if ( input_array[i] == 1; ) {
// then add 1 to hist[1]
// etc.
}
}
You're not a million miles away from a good solution. If you already have count available to pass in, that's handy. Otherwise, you can replace it with:
sizeof(input_array)/sizeof(double)
If you know for sure the maximum value that can appear in input array, then the rest of the problem should be pretty easy.
Loop through each item in input_array, like you're already doing. Then increment the index of histwhich relates to the value of the current item, like so:
for(int i = 0; i<count; i++){
hist[input_array[i]]++;
}
This should give the output you're looking for. For future reference, this is called a count occurrence algorithm.
The function can look the following way
size_t create_hist( const double in[], size_t n, int out[] )
{
const size_t N = 17;
memset( out, 0, N * sizeof( *out ) );
for ( size_t i = 0; i < n; i++ ) ++out[( size_t )in[i]];
size_t m = 0;
for ( size_t i = 0; i < N; i++ )
{
if ( out[i] ) ++m;
}
return m;
}
Here is a demonstrative program
#include <stdio.h>
#include <string.h>
#define SIZE 17
size_t create_hist( const double in[], size_t n, int out[] )
{
const size_t N = SIZE;
memset( out, 0, N * sizeof( *out ) );
for ( size_t i = 0; i < n; i++ ) ++out[( size_t )in[i]];
size_t m = 0;
for ( size_t i = 0; i < N; i++ )
{
if ( out[i] ) ++m;
}
return m;
}
int main(void)
{
double a[] = { 0, 1, 1, 2, 3, 4, 4 };
int b[SIZE];
size_t n = create_hist( a, sizeof( a ) / sizeof( *a ), b );
printf( "There are %zu unique elements\n", n );
for ( size_t i = 0; i < SIZE; i++ ) printf( "%d ", b[i] );
putchar( '\n' );
return 0;
}
Its output is
There are 5 unique elements
1 2 1 1 2 0 0 0 0 0 0 0 0 0 0 0 0

segmentation fault core dump in kruskal's algorithm

#include<stdio.h>
int find( int, int parent[10] );
int uni( int, int, int parent[10] );
int main()
{
int i, j, k, a, b, u, v, n, ne = 1;
int min, mincost = 0, cost[9][9], parent[9];
printf( "\n\tImplementation of Kruskal's algorithm\n" );
printf( "\nEnter the no. of vertices:" );
scanf( "%d", &n );
printf( "\nEnter the cost matrix:\n" );
for ( i = 1; i <= n; i++ )
{
for ( j = 1; j <= n; j++ )
{
printf( "Enter the cost of the edge(%d,%d)=", i, j );
scanf( "%d", &cost[i][j] );
if ( cost[i][j] == 0 )
{
cost[i][j] = 999;
}
}
}
printf( "The edges of Minimum Cost Spanning Tree are\n" );
while ( ne < n )
{
for ( i = 1, min = 999; i <= n; i++ )
{
for ( j = 1; j <= n; j++ )
{
if ( cost[i][j] < min )
{
min = cost[i][j];
a = u = i;
b = v = j;
}
}
}
u = find( u, parent );
v = find( v, parent );
if ( uni( u, v, parent ) == 1 )
{
printf( "%d edge (%d,%d) =%d\n", ne++, a, b, min );
mincost += min;
}
cost[a][b] = cost[b][a] = 999;
}
printf( "\n\tMinimum cost = %d\n", mincost );
}
int uni( int i, int j, int parent[10] )
{
if ( i != j )
{
parent[j] = i;
return 1;
}
return 0;
}
int find( int i, int parent[10] )
{
while ( parent[i] )
{
i = parent[i];
}
return i;
}
It is not able to calculate u,v,uni... i am able to enter the values but i am getting a message segmentation fault (core dumped). i guess there is some problem with the function find and uni(may be in passing of the array parent)..
Without trying to decipher what the code is actually about (single-letter variables, zero comments, no link to this "Kruskal's algorithm" or anything), and in addition to what I already wrote in my comment about adding printf()s to log intermediate values, checking scanf() return codes, mirroring user input back at the user, and sprinkling your code with assert()s...
int parent[9] is declared, but not initialized. find() uses the (uninitialized) contents. Undefined behaviour right there.
Various "fishy" details, like main() declaring parent[9] and cost[9][9], but the functions declaring parent[10]. You also let the user enter the number of vertices, but happily assume that it won't be more than 9 when you use that number as upper loop bound. If any of your assumptions on the amount of storage provided doesn't hold, you're looking at out-of-bounds accesses.
At this point of the code review I'd toss down the code printout on the desk, and give you one of those long, hard stares...

Resources