Recursive binary search implementation is crashing... why? - c++

I'm trying to find and fix what is wrong with this code. It's a binary search implemented by recursion. I dont know why it's returning stack overflow and crashing.
bool find( const int x, const int* pBegin, const int* pEnd)
{
int medel = (*pBegin +(( *pEnd-1) - *pBegin)/2) ;
if(x == medel)
return true ;
else if( x > medel)
{
int begin = (medel +1);
return find (x, &begin, pEnd);
}
else if( x< medel)
{
int last = (medel-1);
return find(x,pBegin, &last);
}
}
void main()
{
int arr[10];
for (int i=0;i<10;++i)
arr[i] = i;
bool hittat = find(7, &arr[0], &arr[9]);
cout << "hittat = " << hittat << endl;
system("pause");
}
When I debug the code, I see that when the function "find" is called it takes weird arguments, like in this pic.
It should take 0 and 9, not these huge numbers :/
Is there anything wrong with my pointers?

You should compute the average of the pointers and check what it's the value of the element hallway between them. Instead you compute the average of the values pointed by them which is significantly different.

You're using medel (I'm assuming that should be middle) as a pointer to an int in some places, but as an int in others.
Try declaring it like this:
const int* middle = pBegin + (pEnd - pBegin + 1) / 2;
Then, when you want to access what is stored there, use *medel.
Also, you'll need a second terminating condition (for when it won't be found). Something like:
if (((middle == pEnd) && (x > *middle)) ||
((middle == pBegin) && (x < *middle))) {
// Terminating condition
return false;
}

You are mixing pointer on int and int with your medel, just set it to be a pointer and access his data with *medel

The problem shown in your picture looks like it was taken from your original code as seen in a prior question. There you had pEnd pointing past the end of an array, so that dereferencing it was not allowed (and yields weird values).
That should not occur with the code as posted.
Your current code only uses pointers to valid integers. But most of those don't point into your array, so what you do is not a search in your array. The program simply does calculations with integers. Only the values of the first and last element of your array are ever used.
The program is confusing, because you pass around the integer values as pointers to their storage. While you start with pointers into your array, you then mix in pointers to automatic variables (beginand end), where you have stored a calculated value. (You never use pointers to array elements other than the first and last.

Related

How to find index of max array element recursively

I want to find the index of biggest element of an array recursively. The declaration of the function can be like this:
int maxIndex(const int *p, int size)
I was studying recursion and I saw some examples, like finding the max array element recursively. That is simple like this:
int maxInt( const int * p, int size)
{
if(size == 1)
return *p;
int max = maxInt(p + 1, size -1 );
if(max > *p)
return max;
else
return p[0];
}
And I asked myself that how can I find the index which includes max element of the array.
I am not even sure it is possible. What do you think?
It is definitely possible: all you need to do is to modify code to return a pointer to max int, and then subtracting the initial pointer from the return value of maxInt in C, or using std::distance in C++.
const int* maxInt( const int * p, int size) {
if(size == 1)
return p;
int *maxPtr = maxInt(p + 1, size -1 );
if(*maxPtr > *p)
return maxPtr;
else
return p;
}
In C:
int index = maxInt(array, size) - array;
In C++:
ptrdiff_t index = std::distance(maxInt(array, size), array);
Note: Solving this problem using recursion should only be considered as part of a learning exercise, because of a very real possibility of overflowing the stack. The same applies to any other problem with potentially high number of recursive invocations and no tail call optimization.
Let's make a bonus question out of it. What's the main problem with recursion here? The main problem is that you end up having as many times maxInt called as you have elements. This is going to happen at the same time, i.e., call stack will look following:
maxInt
maxInt
maxInt
...
Given that the call stack is limited to several hundreds call on modern systems (even less, may be) this solution isn't practical. However, can we make it more practical? Yes, we can - if we transform the current recursion into something which is called tail recursion - that is, when recursion call is happening at the very end of the function - we can employ so-called 'tail-call optimization', which makes sure the recursion does not actually call a function, but behaves like a loop, and end up with the flexibility and performance of the loop. Like I said, the key is to make sure the function is called in the end. Here is how we can do this:
int maxInt( const int * p, int size, int curr_max)
{
curr_max = (curr_max > *p) ? curr_max : *p;
if(size == 1)
return curr_max;
return maxInt(p + 1, size -1, curr_max);
}
If you look into assembly language generated for this function is any optimization above O1, you will see that there is no recursion function call there, but instead there is a loop.
This solution can than be combined with one from dasblinkenlight to provide a solution to OP's homework.
Here's what you want with the function header you want. The index returned from maxInt needs to be adjusted at each level of recursion, which I do with the + 1 part.
int maxInt(const int* p, int size)
{
if (size == 1)
{
return 0;
}
int max = maxInt(p + 1, size - 1) + 1;
return p[max] > *p ? max : 0;
}
Keep in mind that every time the code in the question returns, it is returning the value pointed to, and not its index in the array (*p and p[0]).
to find the first index of a number....if same element are occurring multiple times example [9,8,10,8] and we have to find the first index of element 8.
int firstIndex(int input[], int size, int x) {
if(size==0)
{
return -1;
}
if(input[0]==x)
{
return 0 ;
}
int ans = firstIndex(input+1,size-1,x);
if(ans==-1)
{
return -1;
}else if(ans!=-1)
{
return ans+1;
}
}

After passing by reference to modify an array, why it stays the same?

I am practicing pointers by creating a Big Number struct, which has numDigits (number of digits) and digits (contents of the big number).
I create a function called removeZero(). After passing the integer array and the size n into it, because of passing by reference, I am supposed to cut down the leading zeros for my input. It works, when the integer array is in main function. However, when I pass an array that is in readDigits, it does not return with a non-leading-zero version. Why? How to fix it?
struct BigNum{
int numDigits;
int *digits; //the content of the big num
};
int main(){
int A[] = {0,0,0,0,0,0,1,2,3};
int n=9;
int *B=A;
//removeZero(A,n); If I use this, it cannot compile
//error: invalid initialization of non-const reference of type ‘int*&’ from an rvalue of type ‘int*’
removeZero(B,n);
for (int i=0; i<n; i++){
std::cout << *(B+i) << std::endl;
}
BigNum *num = readDigits();
return 0;
}
BigNum* readDigits(){
std::string digits;
std::cout << "Input a big number:" << std::endl;
std::cin >> digits;
//resultPt in heap or in stack?
int *resultPt = new int[digits.length()]; //in heap
int n = digits.length();
toInt(digits,resultPt);
removeZero(resultPt,n);
//Output the leading zeros, why?
for (int i=0; i<n; i++){
std::cout << *(resultPt +i) << std::endl;
}
BigNum *numPtr = new BigNum();
numPtr->numDigits = n;
numPtr->digits = resultPt;
return numPtr;
}
void toInt(std::string& str, int *result){
for (int i=0;i<str.length() ;i++ ){
result[str.length()-i-1] = (int)(str[i]-'0');
}
}
void removeZero(int* &A,int& n){
int i=0;
while (A[i]==0){
i++;
}
A=A+i; //memory leak?
n=n-i;
}
bool areDigits(std::string num){
for(int i=0;i<num.length();i++){
if(num[i]<'0' || num[i] >'9'){
return false;
}
}
return true;
}
Note that an array and a pointer are two different things. When you pass an array to a function, it degrades to a const pointer. This means that you cannot pass an array to a function which expects a int*&.
It could be the problem of scope of numPtr.numPtr is local variable of function readDigits(). Instead of returning pointer. Pass num to readDigits().
The signature of your removeZero function is:
void removeZero(int* &A,int& n);
That means the forst parameter is a reference of a pointer but the pointer is a non-const one, and you cannot therefore pass an array there, as array is a constant pointer (starting address cannot be changed).
In fact you are changing the starting address within removeZero.
With removeZero, the while loop shopuld be changed from:
while (A[i]==0){
to:
while ((A[i]==0) && (i<n)){
You have a logic error in toInt.
void toInt(std::string& str, int *result){
for (int i=0;i<str.length() ;i++ ){
// This stores the digits in the reverse order.
result[str.length()-i-1] = (int)(str[i]-'0');
}
}
That line should be
result[i] = (int)(str[i]-'0');
If you intend to keep the digits in reverse order, then removeZero has to be changed keeping that in mind.
`
When you say
int *B=A;
you are just creating a pointer to point to the same memory
of the Array A. Just by incrementing the pointer(*B) within the function
removeZero
A=A+i;
you are not deleting anything but you are just incrementing the pointer(*B)
to point to subsequent memory location within the array.
The original array memory pointed to by A remains the same, since you
have not changed any contents of the array, but you have just
incremented a pointer pointing to the same memory location as that of the array.
Also there are so many problems, like "Debasish Jana" mentioned,
you have to change your while loop. ""Code-Apprentice" gave you the reason for your
compilation error when you uncomment your commented code.
Also within "removeZero" you are incrementing A by i instead of "1" like
A=A+1;
This is one of the reason for the strange behavior you experience
Even after changing all this, you cannot see your array getting changed,
since you are not modifying any of the contents of your array.
If you really want to delete the contents of the array and change it dynamically,
you have to go for Vector<>. With static memory allocation you cannot cut the
array size short by removing some elements here and there. Learn Vector<>!

C++ Pointer Dereferenced Assignment

I am trying to learn C++ by firstly going through the low level details before I start using abstractions such as std::copy or memcpy. Currently I am stuck in trying to figure out why this code is never assigning into "sortedArray" variable, when looking with debugger I dereference the value from "data" correctly but it is never assigned to "sortedArray". I see value such as "-842150451" instead of "14" for first value. Can you please help me figure out what I am doing wrong ? And any other issues there may be that I do not see or advice would be greatly appreciated !
void swap(int* bigger, int* smaller){
*bigger += *smaller;
*smaller = *bigger - *smaller;
*bigger = *bigger - *smaller;
}
int* bubbleSort(int *data, int size){
bool swapped = true;
int *sortedArray = (int*)malloc(size*sizeof(int));
for (int i = 0; i < size;i++){
*(sortedArray++) = *(data++);
}
while (swapped){
swapped = false;
for (int i = 1; i <= size - 1; i++){
if (sortedArray[i - 1] > sortedArray[i]){
swap(&sortedArray[i - 1], &sortedArray[i]);
swapped = true;
}
}
size--;
}
return sortedArray;
}
*(sortedArray++) = *(data++); modifies the pointer so it no longer points to the start of the allocated memory. So, later on sortedArray[i] is whatever happens to be in memory past the array, and accessing it is undefined behavior.
If you must use pointers, a quick fix is to use a temporary one, like:
int *sortedArray = (int*)malloc(size*sizeof(int));
int* s = sortedArray;
for (int i = 0; i < size;i++){
*s++ = *data++;
}
Another way would be:
int *sortedArray = (int*)malloc(size*sizeof(int));
for (int i = 0; i < size;i++){
sortedArray[i] = data[i];
}
But, the best way would be to use standard containers and algorithms, like vector and sort.
Here's a demo of the first fix in action.
Change
*(sortedArray++) = *(data++);
to
sortedArray[i] = data[i];
You need to leave intact the pointer to the block of memory you allocated, so you can use it (and free it) later.
Note, there is nothing to be gained by using the *(x+y) syntax instead of x[y], they are equivalent but the latter is easier to read.
In C++ you should not use malloc. Instead use new int[size]. For int there is no difference other than reduced risk of making a typo, however for non-trivial types malloc will not construct them correctly.
That is not C++ at all. You can write generic code that takes a begin iterator and an end iterator in order for it to work with any kind of container that supports such semantic.
template<typename IT>
void bubble_sort(IT begin, IT end) {
while (true) {
bool swapped = false;
for (IT i = begin; i != end-1; i = i+1) {
if (*i > *(i+1)) {
std::iter_swap(i, i+1);
swapped = true;
}
}
if (swapped == false) return;
}
}
Live demo
Where std::iter_swap is like std::swap but works on iterators. You can see iterators as a pair of pointers to the beginning and (past the) end of a container.
You first pointer sortedArray points to some allocated memory.
Then in the first for loop you increment the pointer. not it doesn't point to that memory anymore.
Simply use a temporary pointer for the memory copy.
int* t = sortedArray ;
And now use t in your for loop which copies the data.
Instead of the temporary variable, you can rather count the number of times you called sortedArray++ in your for loop.
If you take a look: for (int i = 0; i < size;i++) you will see that the loop took exactly size number of iterations.
Just subtract size from the pointer after the loop and you point back to your allocated memory.
sortedArray -= size ;

using the qsort() function

I'm a student & i looked up this function in a book. It works as it should but i don't quite understand the inner workings of the sortFunction() which is passed to the qsort() function. If some one could explain it in detail, please do. Thanks in advance.
#include<iostream>
#include<stdlib.h>
using namespace std;
//form of sort function required by qsort()
int sortFunction(const void *intOne,const void *intTwo);
const int tableSize = 10;
int main()
{
int i, table[tableSize];
//fill the table with values
for(i = 0; i < tableSize; i++)
{
cout << "Enter value " << (i + 1) << " : ";
cin >> table[i];
}
cout << "\n";
//sort values
qsort((void*)table, tableSize, sizeof(table[0]), sortFunction);
//print the results
for(i = 0; i < tableSize; i++)
{
cout << "Value " << (i + 1) << " : " << table[i] << endl;
}
cout << "\nDone\n";
return 0;
}
int sortFunction(const void *a, const void *b)
{
int intOne = *((int*)a);
int intTwo = *((int*)b);
if (intOne < intTwo)
{
return -1;
}
if (intOne == intTwo)
{
return 0;
}
return 1;
}
If you look at the actual call to qsort...
qsort((void*)table, tableSize, sizeof table[0], sortFunction);
...you'll see it provides:
a void* address and the size (in bytes) of the entire data array to be sorted, then
the size of one data element in that array, then
a pointer to the comparison function "sortFunction".
There's no argument passed that allows qsort to know what the type of the element is - i.e. how the individual bits in any single data element are used to represent some data value - so there's no way qsort can meaningfully compare two such elements. When you supply...
int sortFunction(const void *a, const void *b)
{
int intOne = *((int*)a);
int intTwo = *((int*)b);
...and qsort calls it, you're getting two pointers - they're to memory addresses but when qsort calls sortFunction those void pointers still tell you nothing about the data element type, as qsort has no insight itself to pass along. The last two lines of code above are where you - the programmer coordinating the qsort call - reapply the knowledge you've had all along about what the data element type is: in this case, they're ints, so you cast each void* to an int* (using (int*)a), then dereference that int* to get the int at memory address a. Similarly for b. In doing so, you've recovered the two numbers that were there as numbers. Then, the job of sortFunction is to indicate how they should be ordered when sorting finishes. To indicate that a should be first, sortFunction can return any negative value (e.g. -1); if they're equivalent, return 0;, and if b should be first, return any positive value (e.g. 1). qsort() receives that information and uses it to work out how to shuffle the data elements around as it sorts.
FWIW, C lets you express that a bit more succinctly as...
return intOne < intTwo ? -1 :
intOne == intTwo ? 0 :
1;
...or (faster, but relying on boolean comparison results being 0 and 1, which may confuse some programmers reading your code)...
return (intOne > intTwo) - (intOne < intTwo);
...or, if you're sure the following can never be mathematically less than INT_MIN (such values wrap around to a big positive number inappropriately)...
return intOne - intTwo;
sortFunction isn't actually doing the sorting, it is being used as a comparison function to determine whether one element should precede another in the sorted list.
What you called 'sortFunction' is normally called a comparator. It basically tells the generic sort code in qsort() whether two elements in the array being sorted compare equal (0), or whether the first argument sorts before the second (<0) or the first argument sorts after the second (>0).
With that information, plus the size of each row, plus the number of rows in the array and the start of the array, the qsort() function can order the data correctly.
As you can see in documentation, qsort function takes a comparator as it's last parameter. This function is used to actually compare parameters (tell which one should go first in a sorted array).

Int Array Length C++

I have to use a dynamic length int array in my program, and want to be able to get the number of objects in it at various points in my code. I am not that familiar with C++, but here is what I have. Why is it not giving me the right length? Thanks.
<#include <iostream>
Using Namespace std;
int length(int*);
void main()
{
int temp[0];
temp[0] = 7;
temp [1] = 10;
temp[2] = '\0';
cout << length(temp) << endl;
}
int length(int* temp)
{
int i = 0;
int count = 0;
while (*temp + i != '\0')
{
count++;
i++;
}
return count;
}
currently it just goes into an endless loop ;_;
In C++ arrays are not dynamic. Your temp array has zero length, and attempting to write to members beyond its length is undefined behaviour. It's most likely not working as it will be writing over some part of the stack.
Either create a fixed size array with enough space to put everything you want to in it, or use a std::vector<int> which is a dynamic data structure.
#include <iostream>
#include <vector>
using namespace std;
int length(int*);
int main () // error: ‘::main’ must return ‘int’
{
int temp[3];
temp[0] = 7;
temp[1] = 10;
// don't use char constants for int values without reason
temp[2] = 0;
cout << length(temp) << endl;
vector<int> vec_temp;
vec_temp.push_back(7);
vec_temp.push_back(10);
cout << vec_temp.size() << endl;
}
int length(int* temp)
{
int i = 0;
int count = 0;
while (*(temp + i) != 0) // *temp + i == (*temp) + i
{
count++;
i++; // don't really need both i and count
}
return count;
}
For the vector, there's no need to specify the size at the start, and you can put a zero in, and finding the length is a simple operation rather than requiring a loop.
Another bug inside your loop was that you were looking at the first member of the array and adding i to that value, rather than incrementing the pointer by i. You don't really need both i and count, so could write that a couple of other ways, either incrementing temp directly:
int length(int* temp)
{
int count = 0;
while (*temp != 0)
{
++count;
++temp;
}
return count;
}
or using count to index temp:
int length(int* temp)
{
int count = 0;
while (temp[count] != 0)
++count;
return count;
}
This approach is a bad idea for a couple of reasons, but first here's some problems:
int temp[0];
This is an array of 0 items, which I don't even think is permitted for stack elements. When declaring an array like this you must specify the maximum number of values you will ever use: E.g. int temp[10];
This is super important! - if you do specify a number less (e.g. [10] and you use [11]) then you will cause a memory overwrite which at best crashes and at worst causes strange bugs that are a nightmare to track down.
The next problem is this line:
while (*temp + i != '\0')
That this line does is take the value stores in the address specified by 'temp' and add i. What you want is to get the value at nth element of the address specified by temp, like so:
while (*(temp + i) != '\0')
So that's what's wrong, but you should take five minutes to think about a better way to do this.
The reasons I mentioned it's a bad idea are:
You need to iterate over the entire array anytime you require its length
You can never store the terminating element (in this case 0) in the array
Instead I would suggest you maintain a separate value that stores the number of elements in the array. A very common way of doing this is to create a class that wraps this concept (a block of elements and the current size).
The C++ standard library comes with a template class named "vector" which can be used for this purpose. It's not quite the same as an array (you must add items first before indexing) but it's very similar. It also provides support for copying/resizing which is handy too.
Here's your program written to use std::vector. Instead of the 'length' function I've added something to print out the values:
#include <vector>
#include <iostream>
void print(std::vector<int> const& vec)
{
using namespace std;
for (size_t i = 0; i < vec.size(); i++)
{
cout << vec[i] << " ";
}
cout << endl;
}
int main()
{
std::vector<int> temp;
temp.push_back(7);
temp.push_back(10);
print(temp);
return 0;
}
You could try:
while (*(temp + i) != '\0')
Your current solution is calculating temp[0] + i (equals 7+i), which apparently is not what you want.
Not only C++ arrays are not dynamic as Pete points out, but only strings (char *) terminate with '\0'. (This is not to say that you can't use a similar convention for other types, but it's rather unusual, and for good reasons: in particular, relying on a terminator symbol requires you to loop through an array to find its size!)
In cases like yours it's better to use the standard library.
#include <vector>
#include <iostream>
int main()
{
std::vector<int> v;
v.push_back(7);
v.push_back(10);
std::cout << v.size() << std::endl;
return 0;
}
If you don't want to use std::vector, try this:
#include <iostream>
using namespace std;
int main () {
int vet[] = {1,2,3,4,5,6};
cout << (sizeof (vet) / sizeof *(vet)) << endl;
return 0;
}
The most common way to get the size of a fixed-length array is something like this:
int temp[256];
int len = sizeof (temp) / sizeof (temp[0]);
// len == 256 * 4 / 4 == 256 on many platforms.
This doesn't work for dynamic arrays because they're actually pointers.
int* temp = new int[256];
int len = sizeof (temp) / sizeof (temp[0]);
// len == 4 / 4 == 1 on many platforms.
For a dynamic-length array if you care about the size, you're best off storing it somewhere when you allocate the array.
The problem with your loop, as pointed out by many is that you have an operator precedence problem here:
*temp + i
should be:
*(temp + i)
But the bigger problem, also pointed out above, is that you don't appear to understand pointers versus fixed-length arrays and are writing off the end of your array.
If you want to use array properly, you have to allocate enough memory for storing values. Once you specified its length, you can't change it. To know array size, you should store it in variable e.g.:
int n;
cin>>n;
int array = new int[n];
int array_length=n;
If you want to change array's length, best way is to use std container, for example std::vector.
Here is the answer to your question
int myarr [] = {1, 2, 3, 4, 5};
int length = sizeof(myarr) / sizeof(myarr[0]);
cout << length;
Because you only allocate space for an array of zero elements.
The following lines
temp [1] = 10;
temp[2] = '\0';
do not allocate more memory or resize the array. You are simply writing data outside the array, corrupting some other part of the application state. Don't do that. ;)
If you want a resizable array, you can use std::vector (and use the push_back member function to insert new values)
A vector also has the size() member function which tells you the current size.
If you want to use the primitive array, you have to track the size yourself. (and, when resizing the array is necessary, copy all elements from the old array to the new, larger one)
To get dynamic behavior in arrays, use a std::vector, or fall back on the old school c style using int * with manual memory allocation (new and delete)[*]
[*] C implementations (discussed in the context of character arrays as C dynamic string length) used malloc, realloc, and free, but these should be avoided in c++ code.
Try this out:
int length(int* temp)
{
int count = 0;
while (*temp != 0 && *temp != -858993460)
{
++count;
++temp;
}
return count;
}