Overflow happening because of addition? - c

Hello and sorry for lame title of this post, just couldn't find a better one.
So, I'm solving Codility exercise called NumberOfDiscIntersections. The solution requires some basic sorting and some minor arithmetic operations. I have achieved 93% result, and only one test is failing. The descripton that they provide is following:
For example, for the input [1, 2147483647, 0] the solution returned a wrong answer (got -1 expected 2).
Problem can be seen here.
And here is my solution:
typedef long long int my_type; //can't use unsigned!
#define LIMIT 10000000
//method used by qsort()
int comp(const void* left, const void* right) {
my_type arg1 = *(const my_type*)left;
my_type arg2 = *(const my_type*)right;
if(arg1 < arg2) return -1;
if(arg2 < arg1) return 1;
return 0;
}
int solution(int A[], int N) {
// write your code in C99 (gcc 6.2.0)
//allocate two arrays to hold beginning and ending points of each circle
my_type *lower = calloc(N, sizeof(my_type));
my_type *upper = calloc(N, sizeof(my_type));
int i;
my_type count = 0;
//initialize arrays
for(i = 0; i < N; i++) {
lower[i] = i - A[i];
upper[i] = i + A[i];
}
qsort(lower, N, sizeof(my_type), comp);
qsort(upper, N, sizeof(my_type), comp);
int open = 0;
int upper_index = 0;
for(i = 0; i < N; i++) {
while(lower[i] > upper[upper_index]) {
//printf("closing %d\n", upper[upper_index]);
upper_index++;
open--;
}
open++;
count += (open-1);
//printf("opening %d\n", lower[i]);
}
free(lower);
free(upper);
return ((int)count <= LIMIT) ? (int)count : -1;
}

The right hand side of these
lower[i] = i - A[i];
upper[i] = i + A[i];
performs int addition. You must cast one of the operands:
lower[i] = (my_type)i - A[i];
upper[i] = (my_type)i + A[i];
to prevent integer overflow.

Related

Sorting a structure

I wanted to sort this problem in C with something like bubble sort ... anyone can help
Implement a list with 5 struct Point (Being this a point w/ X, y);
Sort the 5 struct point (first evaluate x then y).
Example:
// The points
p[0]={2,3}
p[1]={4,5}
p[2]={1,5}
p[3]={4,3}
p[4]={1,2}
// Should become
p[0]={1,2}
p[1]={1,5}
p[2]={2,3}
p[3]={4,3}
p[4]={4,5}
If you want to sort structures, you still have to break it down into comparing numeric types. With this in mind, let's take your example with the points:
struct tagPoint
{
int x;
int y;
};
typedef struct tagPoint Point;
Now, let's suppose you have an array of Point and you want it sorted. You can take two approaches:
1. Straightforward function which sorts the array:
Just make the function to sort the array:
void SortPointArray(Point* Points, unsigned int n)
{
/* This will sort the points with priority on the x and then the y value in ascending order. */
for(unsigned int i = 0; i < n-1; i++)
for(unsigned int j = i+1; j < n; j++)
{
if (Points[i].x > Points[j].x)
{
Point aux = Points[i];
Points[i] = Points[j];
Points[j] = aux;
}
else if ((Points[i].x == Points[j].x) && (Points[i].y > Points[j].y))
{
Point aux = Points[i];
Points[i] = Points[j];
Points[j] = aux;
}
}
}
2. Wrap the algorithm in a generic function and use callbacks for each type you want to sort:
This is a little more complicated, but it will save you some time if you use it frequently. Here, this function uses the same algorithm as the one above, but can sort any types.
void Sort(void* lpArray, unsigned int n, size_t cbSize, int (*Cmp)(void*, void*), void (*Swap)(void*, void*))
{
for(unsigned int i = 0; i < n-1; i++)
for(unsigned int j = i+1; j < n; j++)
/* Cast void* to char* to get rid of warning with pointer arithmetic... */
if ( Cmp( ((char*)lpArray) + i*cbSize, ((char*)lpArray) + j*cbSize) )
Swap( ((char*)lpArray) + i*cbSize, ((char*)lpArray) + j*cbSize );
}
As you can see, it requires 2 more functions passed as parameters. If you want this Sort function to know how to sort the Point array, you must define a Comparrison function and a Swapping function and tell the Sort function to use them.
Here is how i implemented them:
/** This function return 1 if p1 should be swapped with p2. */
int ComparePoints(void* vp1, void* vp2)
{
Point *p1, *p2;
p1 = vp1;
p2 = vp2;
if (p1->x > p2->x)
return 1;
else if ((p1->x == p2->x) && (p1->y > p2->y))
return 1;
return 0;
}
/** This will swap 2 points. */
void SwapPoints(void* vp1, void* vp2)
{
Point p = *(Point*)vp1;
*(Point*)vp1 = *(Point*)vp2;
*(Point*)vp2 = p;
}
How do you use them?
If you only want to use the first SortPointArray function, this is enough:
int main()
{
Point Array[10];
/* Read the points. */
for(unsigned int i = 0; i < 10; i++)
scanf("%d %d", &Array[i].x, &Array[i].y);
SortPointArray(Array, 10);
/*Print the points.*/
for(unsigned int i = 0; i < 10; i++)
printf("%d %d\n", Array[i].x, Array[i].y);
return 0;
}
But if you want to use the generic Sort function (which i recommend only if you have multiple types you want to sort like Points, Lines etc) you have to define the two callbacks (ComparePoints and SwapPoints)
int main()
{
Point Array[10];
/* Read the points. */
for(unsigned int i = 0; i < 10; i++)
scanf("%d %d", &Array[i].x, &Array[i].y);
Sort(Array, 10, sizeof(Point), ComparePoints, SwapPoints);
/*Print the points.*/
for(unsigned int i = 0; i < 10; i++)
printf("%d %d\n", Array[i].x, Array[i].y);
return 0;
}
The OP is asking for a C solution, so here you go:
void bsortDesc(struct yourStruct list[80], int s)
{
int i, j;
struct yourStruct temp;
for (i = 0; i < s - 1; i++)
{
for (j = 0; j < (s - 1-i); j++)
{
if (list[j].marks < list[j + 1].marks)
{
temp = list[j];
list[j] = list[j + 1];
list[j + 1] = temp;
}
}
}
}
Also, here's what I got it from: here.

Split an int array in a C function and return 2 different arrays

I try to split an int array. This array contains positive and negative numbers and I want the function to return 2 arrays one with the positive numbers and one with the negative numbers.
I already tried the following code but it doesn't work as expected.
int main(void)
{
int array[] = {1, -1, 2, 3, 4, -5, 6};
int cnt = sizeof(array)/sizeof(array[0]);
int *neg, *pos;
int **low = &neg;
int **high = &pos;
neg = (int*) malloc(sizeof(int) * 2);
pos = (int*) malloc(sizeof(int) * 5);
sort(array, cnt, low, high);
for(int i = 0; i < 5; i++)
{
printf("%3d\n", pos[i]);
}
//same for negative array
return 0;
}
int sort(int *arr, int cnt, int **low, int **high)
{
for(int i = 0; i < cnt; i++)
{
if(arr[i] > 0)
{
*high[0] = arr[i];
**high++;
}
else
{
*low[0] = arr[i];
**low++;
}
}
}
If someone could show me what I am doing wrong would help a lot.
As mentioned in the comments, the double indirection with int** is unnecessary. A more suitable interface to the function is shown below.
It takes as input the array and count, and pointers to large enough output arrays. As output, the arrays are filled with the positive (negative) values, and the count for each is written to *npos (*nneg).
Treatment of zeroes is left to you. Just edit the if conditions.
Also note how I use *npos += 1 instead of (*npos)++ to avoid mistakes with operator precedence.
void separate(int *arr, int cnt, int *neg, int *pos, int *nneg, int *npos)
{
*nneg = 0;
*npos = 0;
for(int i = 0; i < cnt; i++)
{
if (arr[i] > 0)
{
pos[*npos] = arr[i];
*npos += 1;
}
else if (arr[i] < 0)
{
neg[*nneg] = arr[i];
*nneg += 1;
}
}
}
While in your example you know how many positive and negative values there are, in general you should allocate arrays that are definitely large enough, i.e. cnt elements.

Is there a way to iterate over order?

How can one iterate through order of execution?
I am developing a piece of software that have several steps to compute over some data, and i was thinking in may changing the order of those steps pragmatically so i can check what would be the best order for some data.
Let me exemplify: I have let's say 3 steps (it's actually more):
stepA(data);
stepB(data);
stepC(data);
And I want a contraption that allow me to walk thought every permutation of those steps and then check results. Something like that:
data = originalData; i=0;
while (someMagic(&data,[stepA,stepB,stepC],i++)){
checkResults(data);
data = originalData;
}
then someMagic execute A,B then C on i==0. A, C then B on i==1. B, A then C on i==2 and so on.
You can use function pointers, maybe something like the following:
typedef void (*func)(void *data);
int someMagic(void *data, func *func_list, int i) {
switch (i) {
case 0:
func_list[0](data);
func_list[1](data);
func_list[2](data);
break;
case 1:
func_list[0](data);
func_list[2](data);
func_list[1](data);
break;
case 2:
func_list[1](data);
func_list[0](data);
func_list[2](data);
break;
default: return 0;
}
return 1;
}
func steps[3] = {
stepA,
stepB,
stepC
}
while (someMagic(&data, steps, i++)) {
....
}
The key is to find a way to iterate over the set of permutations of the [0, n[ integer interval.
A permutation (in the mathematical meaning) can be seen as a bijection of [0, n[ into itself and can be represented by the image of this permutation, applied to [0, n[.
for example, consider the permutation of [0, 3[:
0 -> 1
1 -> 2
2 -> 0
it can be seen as the tuple (1, 2, 0), which in C, translate naturally to the array of integers permutation = (int []){1, 2, 0};.
Suppose you have an array of function pointers steps, then for each permutation, you'll then want to call steps[permutation[i]], for each value of i in [0, n[.
The following code implements this algorithm:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
static void stepA(int data) { printf("%d: %s\n", data, __func__); }
static void stepB(int data) { printf("%d: %s\n", data, __func__); }
static void stepC(int data) { printf("%d: %s\n", data, __func__); }
static void (* const steps[])(int) = {stepA, stepB, stepC,};
static int fact(int n) { return n == 0 ? 1 : fact(n - 1) * n; }
static int compare_int(const void *pa, const void *pb)
{
return *(const int *)pa - *(const int *)pb;
}
static void get_next_permutation(int tab[], size_t n)
{
int tmp;
unsigned i;
unsigned j;
unsigned k;
/* to find the next permutation in the lexicographic order
* source: question 4 (in french, sorry ^^) of
* https://liris.cnrs.fr/~aparreau/Teaching/INF233/TP2-permutation.pdf
. */
/* 1. find the biggest index i for which tab[i] < tab[i+1] */
for (k = 0; k < n - 1; k++)
if (tab[k] < tab[k + 1])
i = k;
/* 2. Find the index j of the smallest element, bigger than tab[i],
* located after i */
j = i + 1;
for (k = i + 1; k < n; k++)
if (tab[k] > tab[i] && tab[k] < tab[j])
j = k;
/* 3. Swap the elements of index i and j */
tmp = tab[i];
tab[i] = tab[j];
tab[j] = tmp;
/* 4. Sort the array in ascending order, after index i */
qsort(tab + i + 1, n - (i + 1), sizeof(*tab), compare_int);
}
int main(void)
{
int n = sizeof(steps) / sizeof(*steps);
int j;
int i;
int permutation[n];
int f = fact(n);
/* first permutation is identity */
for (i = 0; i < n; i++)
permutation[i] = i;
for (j = 0; j < f; j++) {
for (i = 0; i < n; i++)
steps[permutation[i]](i);
if (j != f - 1)
get_next_permutation(permutation, n);
}
return EXIT_SUCCESS;
}
The outer loop in main, indexed by j, iterates over all the n! permutations, while the inner one, indexed by i, iterates overs the n steps.
The get_next_permutation modifies the permutation array in place, to obtain the next permutation in the lexicographical order.
Note that it doesn't work when the permutation in input is the last one (n - 1, ..., 1, 0), hence the if (j != f - 1) test.
One could enhance it to detect this case (i isn't set) and to put the first permutation (0, 1, ..., n - 1) into the permutation array.
The code can be compiled with:
gcc main.c -o main -Wall -Wextra -Werror -O0 -g3
And I strongly suggest using valgrind as a way to detect off-by-one errors.
EDIT: I just realized I didn't answer the OP's question precisely. The someMagic() function would allow a direct access to the i-th permutation, while my algorithm only allows to compute the successor in the lexicographic order. But if the aim is to iterate on all the permutations, it will work fine. Otherwise, maybe an answer like this one should match the requirement.
I've come to a solution that is simple enough:
void stepA(STRUCT_NAME *data);
void stepB(STRUCT_NAME *data);
void stepC(STRUCT_NAME *data);
typedef void (*check)(STRUCT_NAME *data);
void swap(check *x, check *y) {
check temp;
temp = *x;
*x = *y;
*y = temp;
}
void permute(check *a, int l, int r,STRUCT_NAME *data) {
int i, j = 0, score;
HAND_T *copy, *copy2, *best_order = NULL;
if (l == r) {
j = 0;
while (j <= r) a[j++](data);
} else {
for (i = l; i <= r; i++) {
swap((a + l), (a + i));
permute(a, l + 1, r, data);
swap((a + l), (a + i));
}
}
}
check checks[3] = {
stepA,
stepB,
stepC,
};
int main(void){
...
permute(checks,0,2,data)
}

Manipulating a global array in a recursive function

I'm working through an algorithms MOOC and have a small program that takes an array A of ints in arbitrary order, counts the number of inversions (an inversion being the number of pairs (i,j) of array indices with i<j and A[i] > A[j]).
Below is the code I've written. I'm trying to tackle it using a "divide and conquer" approach where we recursively split the input array into two halves, sort each half individually while counting the inversions and then merge the two halves.
The trick is I need to keep track of the number of inversions and sort the arrays, so I pass the original array around the various recursive calls as an argument to the function and pass the count of inversions as a return value.
The code executes correctly through the first set of recursive calls that successively divide and sort [1,5,3], however when I get to the 3rd invocation of mergeAndCountSplitInv it crashes at the line:
sortedArrayLeft = realloc(sortedArrayLeft, sizeof(int)*(rightLen + leftLen));
with the error:
malloc: *** error for object 0x100103abc: pointer being realloc'd was not allocated
I can't see where I'm not using malloc correctly and I've combed through this checking to see I'm doing the pointer arithmetic correctly and can't spot any errors, but clearly error(s) exist.
Any help is appreciated.
// main.c
// inversionInC
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
// function to help with debugging array/pointer arithmetic
void logArrayLenAndContents (char *arrayName, int arrayToPrint[], int arrayLen){
printf("%s\n", arrayName);
printf("len:%d\n", arrayLen);
for (int idx = 0; idx < arrayLen; idx++) {
printf("array[%d]: %d\n", idx, arrayToPrint[idx]);
}
}
int mergeAndCountSplitInv(int sortedArrayLeft[], int leftLen, int sortedArrayRight[], int rightLen)
{
printf("Calling mergeAndCount with sortedArrayLeft:\n");
logArrayLenAndContents("left Array", sortedArrayLeft, leftLen);
printf("...and sortedArrayRight:\n");
logArrayLenAndContents("right Array", sortedArrayRight, rightLen);
int i = 0;
int j = 0;
int k = 0;
int v = 0; // num of split inversions
int* outArray;
outArray = malloc((leftLen + rightLen) * sizeof(int));
while (i < leftLen && j < rightLen) {
if (sortedArrayLeft[i] < sortedArrayRight[j]) {
outArray[k] = sortedArrayLeft[i];
i++;
} else{
outArray[k] = sortedArrayRight[j];
v += leftLen - i;
j++;
}
k++;
}
// if at the end of either array then append the remaining elements
if (i < leftLen) {
while (i < leftLen) {
outArray[k] = sortedArrayLeft[i];
i++;
k++;
}
}
if (j < rightLen) {
while (j < rightLen) {
outArray[k] = sortedArrayRight[j];
j++;
k++;
}
}
printf("Wrapping up mergeAndCount where outArray contains:\n");
logArrayLenAndContents("outArray", outArray, k);
sortedArrayLeft = realloc(sortedArrayLeft, sizeof(int)*(rightLen + leftLen));
return v;
}
int sortAndCount(int inArray[], int inLen){
printf("Calling sortAndCount with:\n");
logArrayLenAndContents("inArray", inArray, inLen);
if (inLen < 2) {
return 0;
}
int inArrayLenPart1 = ceil(inLen/2.0);
int inArrayLenPart2 = inLen - inArrayLenPart1;
int* rightArray = malloc(sizeof(int) * inArrayLenPart2);
rightArray = &inArray[inArrayLenPart1];
int x = sortAndCount(inArray, inArrayLenPart1);
printf("sortAndCount returned x = %d\n\n", x);
int y = sortAndCount(rightArray, inArrayLenPart2);
printf("sortAndCount returned y = %d\n\n", y);
int z = mergeAndCountSplitInv(inArray, inArrayLenPart1, rightArray, inArrayLenPart2);
printf("mergeAndCount returned z = %d\n", z);
return x+y+z;
}
int main(int argc, const char * argv[])
{
static int* testArray;
testArray = malloc(5 * sizeof(int));
for (int i = 0; i<=4; i++) {
testArray[0] = 1;
testArray[1] = 5;
testArray[2] = 3;
testArray[3] = 2;
testArray[4] = 4;
}
int x = sortAndCount(testArray, 5);
printf("x = %d\n", x);
return 0;
}
This happens because the value of sortedArrayLeft gets lost as soon as the function returns. The realocated value does not make it to the caller, so inArray of the sortAndCount may be pointing to freed memory if realloc needs to reallocate and copy.
In order to fix this, pass a pointer to the pointer, letting sortedArrayLeft to propagate back to inArray of sortAndCount:
int mergeAndCountSplitInv(int **sortedArrayLeft, int leftLen, int sortedArrayRight[], int rightLen) {
...
*sortedArrayLeft = realloc(*sortedArrayLeft, sizeof(int)*(rightLen + leftLen));
return v;
}
...
int sortAndCount(int **inArray, int inLen) {
...
int z = mergeAndCountSplitInv(inArray, inArrayLenPart1, rightArray, inArrayLenPart2);
}
...
int x = sortAndCount(&testArray, 5);

C Allocating array of 500 and more longs

So.. I have something like this. It is supposed to create arrays with 10, 20, 50 100 .. up to 5000 random numbers that then sorts with Insertion Sort and prints out how many comparisions and swaps were done .. However, I am getting a runtime exception when I reach 200 numbers large array .. "Access violation writing location 0x00B60000." .. Sometimes I don't even reach 200 and stop right after 10 numbers. I have literally no idea.
long *arrayIn;
int *swap_count = (int*)malloc(sizeof(int)), *compare_count = (int*)malloc(sizeof(int));
compare_count = 0;
swap_count = 0;
int i, j;
for (j = 10; j <= 1000; j*=10) {
for (i = 1; i <= 5; i++){
if (i == 1 || i == 2 || i == 5) {
int n = i * j;
arrayIn = malloc(sizeof(long)*n);
fill_array(&arrayIn, n);
InsertionSort(&arrayIn, n, &swap_count, &compare_count);
print_array(&arrayIn, n, &swap_count, &compare_count);
compare_count = 0;
swap_count = 0;
free(arrayIn);
}
}
}
EDIT: ok with this free(arrayIn); I get this " Stack cookie instrumentation code detected a stack-based buffer overrun." and I get nowhere. However without it it's "just" "Access violation writing location 0x00780000." but i get up to 200numbers eventually
void fill_array(int *arr, int n) {
int i;
for (i = 0; i < n; i++) {
arr[i] = (RAND_MAX + 1)*rand() + rand();
}
}
void InsertionSort(int *arr, int n, int *swap_count, int *compare_count) {
int i, j, t;
for (j = 0; j < n; j++) {
(*compare_count)++;
t = arr[j];
i = j - 1;
*swap_count = *swap_count + 2;
while (i >= 0 && arr[i]>t) { //tady chybí compare_count inkrementace
*compare_count = *compare_count + 2;
arr[i + 1] = arr[i];
(*swap_count)++;
i--;
(*swap_count)++;
}
arr[i + 1] = t;
(*swap_count)++;
}
}
I am sure your compiler told you what was wrong.
You are passing a long** to a function that expects a int* at the line
fill_array(&arrayIn, n);
function prototype is
void fill_array(int *arr, int n)
Same problem with the other function. From there, anything can happen.
Always, ALWAYS heed the warnings your compiler gives you.
MAJOR EDIT
First - yes, the name of an array is already a pointer.
Second - declare a function prototype at the start of your code; then the compiler will throw you helpful messages which will help you catch these
Third - if you want to pass the address of a simple variable to a function, there is no need for a malloc; just use the address of the variable.
Fourth - the rand() function returns an integer between 0 and RAND_MAX. The code
a[i] = (RAND_MAX + 1) * rand() + rand();
is a roundabout way of getting
a[i] = rand();
since (RAND_MAX + 1) will overflow and give you zero... If you actually wanted to be able to get a "really big" random number, you would have to do the following:
1) make sure a is a long * (with the correct prototypes etc)
2) convert the numbers before adding / multiplying:
a[i] = (RAND_MAX + 1L) * rand() + rand();
might do it - or maybe you need to do some more casting to (long); I can never remember my order of precedence so I usually would do
a[i] = ((long)(RAND_MAX) + 1L) * (long)rand() + (long)rand();
to be 100% sure.
Putting these and other lessons together, here is an edited version of your code that compiles and runs (I did have to "invent" a print_array) - I have written comments where the code needed changing to work. The last point above (making long random numbers) was not taken into account in this code yet.
#include <stdio.h>
#include <stdlib.h>
// include prototypes - it helps the compiler flag errors:
void fill_array(int *arr, int n);
void InsertionSort(int *arr, int n, int *swap_count, int *compare_count);
void print_array(int *arr, int n, int *swap_count, int *compare_count);
int main(void) {
// change data type to match function
int *arrayIn;
// instead of mallocing, use a fixed location:
int swap_count, compare_count;
// often a good idea to give your pointers a _p name:
int *swap_count_p = &swap_count;
int *compare_count_p = &compare_count;
// the pointer must not be set to zero: it's the CONTENTs that you set to zero
*compare_count_p = 0;
*swap_count_p = 0;
int i, j;
for (j = 10; j <= 1000; j*=10) {
for (i = 1; i <= 5; i++){
if (i == 1 || i == 2 || i == 5) {
int n = i * j;
arrayIn = malloc(sizeof(long)*n);
fill_array(arrayIn, n);
InsertionSort(arrayIn, n, swap_count_p, compare_count_p);
print_array(arrayIn, n, swap_count_p, compare_count_p);
swap_count = 0;
compare_count = 0;
free(arrayIn);
}
}
}
return 0;
}
void fill_array(int *arr, int n) {
int i;
for (i = 0; i < n; i++) {
// arr[i] = (RAND_MAX + 1)*rand() + rand(); // causes integer overflow
arr[i] = rand();
}
}
void InsertionSort(int *arr, int n, int *swap_count, int *compare_count) {
int i, j, t;
for (j = 0; j < n; j++) {
(*compare_count)++;
t = arr[j];
i = j - 1;
*swap_count = *swap_count + 2;
while (i >= 0 && arr[i]>t) { //tady chybí compare_count inkrementace
*compare_count = *compare_count + 2;
arr[i + 1] = arr[i];
(*swap_count)++;
i--;
(*swap_count)++;
}
arr[i + 1] = t;
(*swap_count)++;
}
}
void print_array(int *a, int n, int* sw, int *cc) {
int ii;
for(ii = 0; ii < n; ii++) {
if(ii%20 == 0) printf("\n");
printf("%d ", a[ii]);
}
printf("\n\nThis took %d swaps and %d comparisons\n\n", *sw, *cc);
}
You are assigning the literal value 0 to some pointers. You are also mixing "pointers" with "address-of-pointers"; &swap_count gives the address of the pointer, not the address of its value.
First off, no need to malloc here:
int *swap_count = (int*)malloc(sizeof(int)) ..
Just make an integer:
int swap_coint;
Then you don't need to do
swap_coint = 0;
to this pointer (which causes your errors). Doing so on a regular int variable is, of course, just fine.
(With the above fixed, &swap_count ought to work, so don't change that as well.)
As I told in the comments, you are passing the addresses of pointers, which point to an actual value.
With the ampersand prefix (&) you are passing the address of something.
You only use this when you pass a primitive type.
E.g. filling the array by passing an int. But you are passing pointers, so no need to use ampersand.
What's actually happening is that you are looking in the address space of the pointer, not the actual value the pointer points to in the end. This causes various memory conflicts.
Remove all & where you are inputting pointers these lines:
fill_array(&arrayIn, n);
InsertionSort(&arrayIn, n, &swap_count, &compare_count);
print_array(&arrayIn, n, &swap_count, &compare_count);
So it becomes:
fill_array(arrayIn, n);
InsertionSort(arrayIn, n, swap_count, compare_count);
print_array(arrayIn, n, swap_count, compare_count);
I also note that you alloc memory for primitive types, which could be done way simpler:
int compare_count = 0;
int swap_count = 0;
But if you choose to use the last block of code, DO use &swap_count and &compare_count since you are passing primitive types, not pointers!

Resources