Problems splitting and searching array segments with pthreads - c

I'm working on a personal project to fill an array with random numbers, split into a number of user defined segments using pthread (POSIX), search for a target in each segment, and return the number of times the target was found. I'm having bugs and issues. For more than one thread, issues like the target not being held in the struct member and a thread not being created and other things happen. I'm sure my logic is off and my code and it's output reflect this, but I'm stumped. How would you split an array into threads? What logic am I messing up?
HEADER FILE...
#ifndef COUNT_ARRAY_H
#define COUNT_ARRAY_H
// structure declarations
typedef struct
{
int threadNum;
int *array;
int first;
int last;
int target;
int numFound;
} ThreadInfo;
// function prototypes
void* ThreadFunc(void *vptr);
#endif // COUNT_ARRAY_H
MAIN FILE....
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include "count_array.h"
int main(void)
{
int numSegs;
int numSegElems;
int maxRand;
int target;
int totalElems;
int totalFound = 0;
ThreadInfo *infoPtr;
pthread_t *threadHandles;
int index = 0;
int first;
int last;
int threadNum = 0;
//get primary info from user...
printf(" Please enter the total number of elements? ");
scanf("%d", &totalElems);
printf(" Please enter the maximum random value: ");
scanf("%d", &maxRand);
printf(" Please enter the number of segments (1 to 15857): ");
scanf("%d", &numSegs);
if(numSegs > 15857)
{
puts(" Too many segments for machine!");
exit(EXIT_FAILURE);
}
numSegElems = totalElems/numSegs;
// configure the array to work with
// declare array here...
int myArray[totalElems];
//and fill array here
for(; index < totalElems; index++)
{
// % rand() and maxRand to get good range and
//not go beyond users max number
myArray[index] = (rand() % maxRand);
//test printf...ignore if still here
printf(" %d \n", myArray[index]);
}
// get the target value to look for
printf(" Please enter the target value: ");
scanf("%d",&target);
// display initial information
printf("*** Begin search: target = %d, # elements = %d, # segments = %d, "
"# segment elements = %d\n"
, target
, totalElems
, numSegs
, numSegElems);
// initialize the array first/last indexes into the integer array
if(numSegs == 1)
{
first = totalElems;
last = 0;
}
else
{
first = totalElems - numSegElems;
last = (first - numSegElems);
}
// allocate an array to store the thread handles
int size; //size of segment
if(numSegs > 1)
{
size = numSegElems;
}
else
{
size = totalElems;
}
//test printf...please ignore if still here
//printf(" size %d \n", size);
int segA[size];//not sure if I need this
// loop and create threads (# of segments)
index = 0;
for(; threadNum < numSegs; index++)
{
// allocate a thread info structure from the heap
threadHandles = calloc(totalElems, sizeof(pthread_t));
infoPtr = calloc(totalElems, sizeof(ThreadInfo));
// store the information in the allocated structure
infoPtr[index].threadNum = threadNum;
infoPtr->target = target;
infoPtr->first = first;
infoPtr->last = last;
infoPtr->array = myArray;
// create the secondary thread, passing the thread info
pthread_create(&threadHandles[index], NULL, ThreadFunc, &infoPtr[index]);
// update the first/last array indexes for the next thread
first = last;
last = first-numSegs;
++threadNum;
}
// loop and join the threads to fetch each thread's results
for(index = 0; index < numSegs; index++)
{
// join with the next thread
pthread_join(threadHandles[index], NULL);
// get the total number of matches from the thread's infoPtr
// and display a message
printf(" *** pthread_join returned: threadNum = %d, numFound = %d\n",
infoPtr[index].threadNum, infoPtr->numFound);
}
// release the infoPtr structure back to the heap
free(infoPtr);
// display the final results
// release heap memory
free(threadHandles);
return 0;
} // end of "main"
void* ThreadFunc(void *vptr)
{
//declare and set vars
ThreadInfo *ptr = vptr;
ptr->numFound = 0;
int index = ptr->first-1;
//test printf...ignore if still here
printf(" Targ %d \n", ptr->target);
//start search
for(; index >= ptr->last; --index)
{
printf(" %d \n", ptr->array[index]);
//if target found
if(ptr->target == ptr->array[index])
{
puts(" Target found! ");
//increment numFound
++ptr->numFound;
}
}
//drop out and display message
}

You've got multiple errors in your allocation of threadHandles and infoPtr. First, you don't really want to be allocating totalElems of them -- you only need numSegs. Second, and more crucially, you're reallocating them and changing the values of the pointers infoPtr and threadHandles every time through the thread invocation loop. Third, you've mixed treating infoPtr as an array of ThreadInfo structures here:
infoPtr[index].threadNum = threadNum;
with treating it as a pointer to a changing ThreadInfo structure here:
infoPtr->target = target;
infoPtr->first = first;
infoPtr->last = last;
infoPtr->array = myArray;
so every time through the loop, you're setting these parameters on the first thread only.
To fix this, edit and move the allocations before the loop and treat infoPtr consistently as an array:
threadHandles = calloc(numSegs, sizeof(pthread_t));
infoPtr = calloc(numSegs, sizeof(ThreadInfo));
for(; threadNum < numSegs; index++)
{
infoPtr[index].threadNum = threadNum;
infoPtr[index].target = target;
infoPtr[index].first = first;
infoPtr[index].last = last;
infoPtr[index].array = myArray;
and also fix up the second use of infoPtr in this printf a little further down:
printf(" *** pthread_join returned: threadNum = %d, numFound = %d\n",
infoPtr[index].threadNum, infoPtr[index].numFound);
and things will work a little better.
There are still more bugs lingering in your setting of first and last. I suggest you print out their values and make sure they are coming out the way you intend. I was able to get them to become negative (and start searching random memory) pretty easily.

Related

problem with dynamic array and pointers in selection sort

i make a program of selection sort using dynamic array and pointers but after running this code i found that array is being sorted if we give the size input like 4 and 6 but does't sort properly if the size input is like 5 and 7 etc ...i also did bubble sort program before this using same technique of pointers and dynamic array but it gave perfect sorted array in all the condition , i also try to debuge the code but still don't understand why this is happening if anyone having idea about this then please help me out .
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
int main()
{
int * ptr,temp,min;
int size,i,j,s;
printf("Enter the size of array:");
scanf("%d",&size);
ptr = (int *)(calloc (size,sizeof(int)));
if(ptr == NULL)
printf("No memory");
else
{
printf("\n=== RANDOM ELEMENTS OF ARRAY ===\n");
for(s=0;s<size;s++)
*(ptr+s) = rand()%100;
for(s=0;s<size;s++)
printf("\nElement [%d] = %d ",s,*(ptr+s));
// selection sort algorithm
for(i=0;i< size-1;i++)
{
min = i;
for(j=i+1;j<size;j++)
{
if(*(ptr+j) < *(ptr+min))
{
min = j;
}
temp = *(ptr+i);
*(ptr+i) = *(ptr+min);
*(ptr+min) = temp;
}
}
// End of algorithm
printf("\n\n======= SORTED ELEMENTS =======\n\n");
for(s=0;s<size;s++)
printf("Element [%d] = %d \n",s,*(ptr+s));
}
}
Your Selection Sort algorithm seems to be wrong. You have to replace the element in the current index with the minimum after the inner for loop finishes iteration:
for(i=0;i< size-1;i++)
{
min = i;
for(j=i+1;j<size;j++)
{
if(*(ptr+j) < *(ptr+min))
{
min = j;
}
}
temp = *(ptr+i);
*(ptr+i) = *(ptr+min);
*(ptr+min) = temp;
}
Now, it should work for all input sizes.
Clearing away a couple of unnecessary confusion factors...
*(ptr + index)
Is identical to
ptr[index]
But the second is much easier to read.
Next, in the following section the variable min is introduced,
if(*(ptr+j) < *(ptr+min))
{
min = j;
}
...but is not necessary for a simple sort. Just stick with i and j and the sort will proceed correctly for either even or odd sets of values. Finally, to eliminate the memory leak, call free(ptr); when ptr is no longer needed. Following is a cleaned up version, with corrections.
int main(void)//added void
{
int * ptr,temp/*,min*/;
int size,i,j,s;
printf("Enter the size of array:");
scanf("%d",&size);
ptr = calloc (size,sizeof(int));//casting is required in C++
//but unnecessary in C.
//(and can be problematic)
if(ptr == NULL)
{
printf("No memory");
}
else
{
printf("\n=== RANDOM ELEMENTS OF ARRAY ===\n");
for(s=0;s<size;s++)
ptr[s] = rand()%100;
for(s=0;s<size;s++)
printf("\nElement [%d] = %d ",s,ptr[s]);
// selection sort algorithm
for(i=0;i< size-1;i++)
{
for(j=i+1;j<size;j++)//removed if section introducing 'min'
{
if(ptr[j] < ptr[i])
{
temp = ptr[i];
ptr[i] = ptr[j];
ptr[j] = temp;
}
}
}
// End of algorithm
printf("\n\n======= SORTED ELEMENTS =======\n\n");
for(s=0;s<size;s++)
printf("Element [%d] = %d \n",s,*(ptr+s));
free(ptr);
}
return 0;//added
}
BTW, this was tested with size == 3 and
ptr[0] = 3;
ptr[1] = 2;
ptr[2] = 1;
along with several other odd and even counts of random values

Initialising a unique pointer in a loop (to be used in a hash table)

For the past several years I have been doing number crunching in Python using dictionaries. I am recapping C after several years, and I am trying to mimic python dictionary functionality using a hash table. My hash table works fine, but I'm struggling with adding new entry's programmatically in a loop. Here is my code:
#define TABLE_SIZE 16
typedef struct item{
char key[64];
int value;
int list[5];
struct item *next;
} item;
// Create hash table array
item *hash_table[TABLE_SIZE];
void init_hash_table(){
for (int i = 0; i < TABLE_SIZE; i++)
hash_table[i] = NULL;
}
int hash(char *key){
unsigned long H = 5381;
int c;
while ((c = *key++))
H = ((H << 5) + H) + c;
H = H % TABLE_SIZE;
int hash = (int)H;
return hash;
}
int insert_item(item *pItem){
if (pItem == NULL){
printf("Invalid item");
return -1;
}
else {
int index = hash(pItem->key);
pItem->next = hash_table[index];
hash_table[index] = pItem;
return index;
}
}
void print_table(){
printf("\n--- Table Start ---\n");
for (int i = 0; i < TABLE_SIZE; i++){
if (hash_table[i] == NULL)
printf("\t %d \t --- \t\n", i);
else {
item *tmp = hash_table[i];
printf("\t %d ", i);
while(tmp != NULL){
printf("\t --- \t %s", tmp->key);
tmp = tmp->next;
}
printf("\n");
}
}
printf("--- Table End ---");
}
int main(){
// Initialise hash table
init_hash_table();
char letters[] = "ABCDEFGHIJ";
// Insert data
for (int i = 0; i < 10; i++){
item itemN = {.key = letters[i]};
printf("%s ", itemN.key);
printf("%p\n", &itemN);
insert_item(&itemN);
}
// Print the table
print_table();
return 0;
}
Essentially I want 10 entries added to the hash table, each unique with the key as a different letter (A to J). The problem is each itemN in main has the same address in memory, so the same pointer is being overwritten each time. Hence my output looks like:
A 0061FEB0
B 0061FEB0
C 0061FEB0
D 0061FEB0
E 0061FEB0
F 0061FEB0
G 0061FEB0
H 0061FEB0
I 0061FEB0
J 0061FEB0
--- Table Start ---
0 ---
1 ---
2 ---
3 --- J
4 ---
5 ---
6 --- J
7 --- J
8 --- J
9 --- J
10 --- J
11 --- J
12 --- J
13 --- J
14 --- J
15 ---
--- Table End ---
The question is, how can I generate a new item variable in the loop with a unique address? This seems like pretty standard functionality to implement, since we cannot always initialise variables manually. Sorry if I am missing something obvious!
Thanks
The basic problem is that your hash table does not actually store items, it stores pointers, and your insert_item function takes a pointer and inserts that pointer directly in the hash table, which means it will only be valid as long as that object is alive. When the lifetime of the object ends, the pointer becomes dangling and your hash table becomes invalid, so pretty much anything after that is undefined behavior.
Whenever you deal with pointers in C (which is pretty much all the time), you need to be aware of the lifetime of the pointed at objects and make sure that the pointer will not be in use after the lifetime ends. In your case, you are defining your item as a local (auto) within a loop in main, so the lifetime will end as soon as that iteration of the loop ends. So by the time you go to put a second item in the hash table, you have a dangling pointer in the table, and all bets are off.
The usual way of dealing with this is to have your hash table "have ownership" of the objects in the table, and have your insert_item make a copy of the item (using malloc to allocate some memory for the copy):
int insert_item(item *pItem){
if (pItem == NULL){
printf("Invalid item");
return -1;
}
else {
int index = hash(pItem->key);
item *copy = malloc(sizeof(item));
if (copy == NULL) {
printf("Ran out of memory\n");
return -1; }
*copy = *pItem;
copy->next = hash_table[index];
hash_table[index] = copy;
return index;
}
}
This way, all the item objects actually in the hash table will have an extended lifetime -- they will live until you explicitly free them. You want to do that when you are done with the hash table itself, so you might have a destroy_table function to do that.
Code keeps inserting the same item. &itemN is the address of the local object itemsN. That item goes out of scope and it no longer valid after the loop { ...}
for (int i = 0; i < 10; i++){
item itemN = {.key = letters[i]};
...
insert_item(&itemN);
}
print_table(); // no longer valid for code to use `&itemN`.
.key = letters[i] is also invalid as that is attempting to assign char to a char *. That implies warnings are not fully enabled. Save time, enable them all.
Perhaps insert 10 different items.
item items[10] = { 0 };
for (int i = 0; i < 10; i++){
items[i].key[0] = letters[i];
printf("%s ", items[i].key);
printf("%p\n", &item[i]);
insert_item(&items[i]);
}
GTG

Problems with passing arrays as parameters

I am a novice programmer in C and am running into an issue that is almost painfully simple. I am writing a basic program that creates two arrays, one of student names and one of student ID numbers, then sorts them and prints them in various ways, and finally allows the user to search the arrays by ID number. Here is the code:
#include <stdio.h>
#include <string.h>
#define ARRAY_SIZE 3
#define MAX_NAME_LENGTH 32
int main()
{
// Student info arrays
char NAME[ARRAY_SIZE][MAX_NAME_LENGTH];
int ID[ARRAY_SIZE];
// Array for student IDs, shifted twice to the right
int shiftedID[ARRAY_SIZE];
// Boolean value to keep while loop running and
// the ID search prompt repeating
int loop = 1;
// Counter variable for the for loop
int counter;
// Gets input values for the student info arrays
for (counter = 0; counter < ARRAY_SIZE; counter++)
{
printf("Input student name: ");
scanf("%s", NAME[counter]);
printf("Input student ID: ");
scanf("%d", &ID[counter]);
}
// Sorts the arrays
sort(NAME, ID);
// Prints the arrays
print_array(&NAME, ID);
// Shifts the ID value two bits to the right
shiftright(ID, shiftedID);
print_array(NAME, shiftedID);
// Repeatedely prompts the user for an ID to
// search for
while(loop == 1)
{
search_id(NAME, ID);
}
}
And here are the function definitions:
#define ARRAY_SIZE 3
#define MAX_NAME_LENGTH 32
// Sorts the two arrays by student ID. (Bubble sort)
void sort(char **nameArray, int idArray[])
{
// Counter variables for the for loop
int firstCounter = 0;
int secondCounter = 0;
for(firstCounter = 0; firstCounter < ARRAY_SIZE; firstCounter++)
{
for(secondCounter = 0; secondCounter < ARRAY_SIZE - 1;
secondCounter++)
{
if(idArray[secondCounter] > idArray[secondCounter + 1])
{
// Temporary variables for the sort algorithm
int tempInt = 0;
char tempName[32];
tempInt = idArray[secondCounter + 1];
idArray[secondCounter + 1] = idArray[secondCounter];
idArray[secondCounter] = tempInt;
strcpy(tempName, nameArray[secondCounter + 1]);
strcpy(nameArray[secondCounter + 1],
nameArray[secondCounter]);
strcpy(nameArray[secondCounter], tempName);
}
}
}
}
// Searches the ID array for a user input student
// ID and prints the corresponding student's info.
void search_id(char **nameArray, int idArray[])
{
// A boolean value representing whether or not
// the input ID value was found
int isFound = 0;
// The input ID the user is searching for
int searchID = 0;
printf("Input student ID to search for: ");
scanf("%d", &searchID);
// Counter variable for the for loop
int counter = 0;
while (counter < ARRAY_SIZE && isFound == 0)
{
counter++;
if (idArray[counter] == searchID)
{
// Prints the name associated with the input ID
isFound = 1;
printf("%s", nameArray[counter]);
}
}
// If the input ID is not found, prints a failure message.
if (isFound == 0)
{
printf("ID not found.\n");
}
}
// Prints the name and ID of each student.
void print_array(char **nameArray, int idArray[])
{
// Counter variable for the for loop
int counter = 0;
printf("Student Name & Student ID: \n");
for (counter = 0; counter < ARRAY_SIZE; counter++)
{
printf("%s --- %d\n", nameArray[counter], idArray[counter]);
}
}
// Shifts the ID value to the right by two bits
void shiftright(int idArray[], int shiftedID[])
{
// Counter variable for the for loop
int counter = 0;
for (counter = 0; counter < ARRAY_SIZE; counter++)
{
shiftedID[counter] = idArray[counter] >> 2;
}
}
I am aware that this program is fairly basic in nature, and more than anything it is an exercise to get me more well versed in a language such as C. I've been working on it for some time, and have worked through several problems, but seem to be stuck on three issues:
If the input ID numbers are not input already in order, a segmentation fault results. If the ID numbers are input already in order, the sort function never passes through the if statement, and no problems arise.
When passing the arrays of names/IDs to the print_array function, the IDs are printed just fine, but the names will be printed either entirely blank or as a series of strange characters.
When searching by ID at the end of the program, the ID number that was entered first (so, the number in ID[0]) displays an ID not found message, where all numbers at index 1 or greater will work fine - aside from the corresponding names that should be printed being printed as blank, as mentioned in the second issue.
Any advice that I can get would be greatly appreciated! I find the power behind the fine details needed in C to be both really interesting but also very confusing, intimidatingly so, and that means any help I can get makes a big difference.
The problem is that you are assuming that char [ARRAY_SIZE][MAX_NAME_LENGTH] and char ** are interchangeable
void sort(char **nameArray, int idArray[])
should be
void sort(char nameArray[][MAX_NAME_LENGTH], int idArray[])
or
void sort(char (*nameArray)[MAX_NAME_LENGTH], int idArray[])
in order to use a pointer to an array of MAX_NAME_LENGTH chars, same for your search_id function.
Take a look to question 6.13 of C-FAQ
I would advise you to restructure your program. Rather than storing two independent arrays for names and IDs, you can store one array of structs which contain all the necessary data:
typedef struct student
{
int id;
char name[MAX_NAME_LENGTH];
} student_t;
student_t students[ARRAY_SIZE];
Now you have a single array which can never become "mismatched" by sorting the IDs without the names, etc.
You can sort an array in C using the standard library function qsort():
qsort(students, ARRAY_SIZE, sizeof(student_t), comparator);
This requires you define a comparator, which is fairly simple. One example would be:
int comparator(const void *lhs, const void *rhs)
{
const student_t *s1 = lhs, *s2 = rhs;
return s1->id - s2->id;
}
You can use the same comparator with another standard library function bsearch() to search the array of students after it is sorted:
student_t key = { 42 }; // name doesn't matter, search by ID
student_t* result = bsearch(&key, students, ARRAY_SIZE, sizeof(student_t), comparator);
These standard functions are more efficient than what you had, and require you to write much less code, with fewer chances for mistakes.

C: insert element in empty heap

i'm supposed to write a code, that inserts numbers from stdin into an at first empty max-heap. my code just doesn't get the order of elements right, i found out, that it doesnt even enter the while loop before the third number. Anybody willing to help? Thanks in advance!
int heap_insert(heap* h, int key) {
if (h->size==MAX_HEAP_SIZE){
return(-1);
}
h->size=h->size+1;
int i=h->size-1;
h->array[i]=key;
int parent=(i-1)/2;
while (i>1 && h->array[parent]< key) {
h->array[i]= h->array[parent];
i = parent;
h->array[i]=key;
}
return(0);
}
it doesnt even enter the while loop before the third number
That part can be answered. Your loop won't go until i is 2 or greater...
while (i > 1 && h->array[parent]< key) {
^^^^^
Here's the code that sets i.
h->size = h->size+1;
int i = h->size-1;
That code is easier to understand like so:
int i = h->size;
h->size++;
First time through, i will be 0 (assuming h->size is initialized to 0, you didn't show your heap init code). Second time it will be 1. Third time it will be 2 and then finally the loop can run.
I'm guessing you want i >= 1 in the while loop so it will go on the second call.
As for why it's not working, the primary problem is you're forgetting to change parent in the loop.
/* i and parent initialized */
int i=h->size-1;
...
int parent=(i-1)/2;
while (i>1 && h->array[parent]< key) {
h->array[i]= h->array[parent];
/* i is changed, but where's parent? */
i = parent;
h->array[i]=key;
}
Here's what it should look like. I've changed i, which should only be used in loop indexes, to the more descriptive new.
/* new and parent initialized */
int new = h->size;
...
int parent = (new-1)/2;
while( new != 0 && h->array[parent] < key ) {
h->array[new] = h->array[parent];
h->array[parent] = key;
/* new AND parent changed */
new = parent;
parent = (new-1)/2;
}
Here's the complete code, plus I made the heap size dynamic because fixed size structures are a crutch best avoided.
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int size;
int max_size;
int *array;
} heap;
#define INIT_HEAP_SIZE 4
static heap *heap_init() {
heap *h = calloc(1, sizeof(heap));
h->max_size = INIT_HEAP_SIZE;
h->array = calloc(h->max_size, sizeof(int));
return h;
}
static void heap_destroy(heap *h) {
free(h->array);
free(h);
}
static void heap_grow(heap *h) {
h->max_size *= 2;
h->array = realloc( h->array, h->max_size * sizeof(int) );
}
static void heap_insert(heap* h, int key) {
if (h->size >= h->max_size) {
heap_grow(h);
}
int new = h->size;
h->size++;
h->array[new] = key;
int parent = (new-1)/2;
while( new != 0 && h->array[parent] < key ) {
h->array[new] = h->array[parent];
h->array[parent] = key;
new = parent;
parent = (new-1)/2;
}
return;
}
int main(void) {
heap *h = heap_init();
heap_insert(h, 23);
heap_insert(h, 11);
heap_insert(h, 42);
heap_insert(h, 5);
heap_insert(h, 99);
for( int i = 0; i < h->size; i++ ) {
printf("%d: %d\n", i, h->array[i]);
}
heap_destroy(h);
}
It doesn't enter the while loop before the 3rd number because your i is not greater than 1 until the 3rd number is entered. At 1st number i = 0, then 1 then 2.
For the loop, here's my advice on figuring out the problem: Suppose you enter the values 3, 5, 7. As soon as 5 is entered, you need a swap. 5 should become the new root, and 3 should be a child. (So maxheap property is kept) Then, when 7 is entered, another swap is in order. This time with 5. 7 becomes root, 3 and 5 are children. What does this tell you about the indexes? What happens if we insert 10, 16, 1 as well? More swaps? If you answer these properly the while loop should be easy to solve. (Hint: You need to keep swapping by starting from the child, and move to next parent until everything is in order)

Segmentation fault in Binary Search in C

I'm trying to write a program that scans an input file that contains the number of letters in the array, a sorted list of letters, the number of letters to search for, a list of letters to search for. It displays the search results in a format shown in the sample file.
I'm getting a segmentation fault error message at runtime with the code I have included below. Now before this post gets negative feedback for not including the right amount of code, I don't really know where the error is with this segmentation fault. I've included the relevant files here on Pastebin:
main.c
#include <stdio.h>
#include <stdlib.h>
#include "Proto.h"
int main()
{
/* Accepts number of elements from user */
scanf("%d", &elements);
/* Creates dynamic array */
array = (char *) calloc(elements, sizeof(char));
/* Copies sorted values to the dynamic array */
for(i = 0; i < elements; i++)
{
scanf("%s", &array[i]);
}
/* Accepts number of elements to search */
scanf("%d", &search);
/* Searches for elements in sorted array one at a time */
for(i = 1; i <= search; i++)
{
/* Accepts value to search */
scanf("%s", &value);
/* Resets counter to 0 */
count = 0;
/* Finds location of element in the sorted list using binary search */
location = binarySearch(array, value, 0, (elements-1));
/* Checks if element is present in the sorted list */
if (location == -1)
{
printf("%4s not found!\n", value);
}
else
{
printf("%4s found at %4d iteration during iteration %4d\n", value, location, count);
}
}
free(array);
}
BinarySearch.c
#include <stdio.h>
#include "Proto.h"
int binarySearch(char * nums, char svalue, int start, int end)
{
middle = (start + end) / 2;
/* Target found */
if (nums[middle] == svalue)
{
return middle;
}
/* Target not in list */
else if( start == end )
{
return -1;
}
/* Search to the left */
else if( nums[middle] > svalue )
{
count++;
return binarySearch( nums, svalue, start, (middle-1) );
}
/* Search to the right */
else if( nums[middle] < svalue )
{
count++;
return binarySearch( nums, svalue, (middle+1), end );
}
}
Proto.h
#ifndef _PROTO_H
#define _PROTO_H
char * array;
int elements, search, location, count, middle, i;
char value;
int binarySearch(char *, char, int, int);
#endif
Sample Input/Output
Sample Input file:
6
a d n o x y
3
n x z
Sample Output file:
n found at 2 during iteration 0.
x found at 4 during iteration 1.
z not found!
I did not check the whole code but I see this error inyour main.c
your code
/* Creates dynamic array */
array = (char *) calloc(elements, sizeof(char));
/* Copies sorted values to the dynamic array */
for(i = 0; i < elements; i++)
{
scanf("%s", &array[i]);
}
is wrong. your array shoud be double pointer char **array
/* Creates dynamic array */
array = calloc(elements, sizeof(char*));
/* Copies sorted values to the dynamic array */
for(i = 0; i < elements; i++)
{
scanf("%ms", &array[i]);
}
Try to divide your code and found out the part wich is the cause of the problem and back a gain with a small part of code this will help to find out the solution

Resources