Debug Assertion [Vector] - c++

I'm wondering if something is wrong with my code especially the vector implementation?
Well,I was just exposed to the use of vector yesterday by people here.
In my college,I only learnt array.So,the usage of vector is kinda new to me.
To my understanding,vector is basically a dynamic array.-Correct me if I were wrong
Well,so lets go with my code.I got the following error: "Vector subscript out of range" after inputting n value.
EDIT:Fixed my earlier issue.Thanks to #quantdev .Now I noticed that my values aren't sorted.
#include<iostream>
#include<vector>
using namespace std;
//Function prototype
void Insertion_sort(vector<int> AR, int n);
void random_store(int val, vector<int> &aVec);
int main()
{
int nvalue;
vector<int> int_vector;
cout << "How many numbers would you like to generate?\n";
cin >> nvalue;//get input from user
random_store(nvalue, int_vector);//pass user input into random() function
system("pause");
return 0;
}
void random_store(int val, vector<int> &aVec)//store randomly generated value
{
int num;//represent random integer output
for (int i = 0; i < val; i++)
{
aVec.push_back(rand() % val + 1);//push each generated value into vector
}
Insertion_sort(aVec,val);//Pass the vector into a function to perform sorting
cout << " \n The sorted array is as follows \n ";
for (int i = 1; i <= val; i++)//Print sorted array
{
cout << " \n Element " << i << " : " << aVec[i] << endl;//will loop from aVec 1st array till n value
}
}
void Insertion_sort(vector<int> AR, int n)//insertion sort function
{
int j, val;//iterate through entire list
for (int i = 1; i < n; i++)
{
val = AR[i];
j = i - 1;
while (j >= 0 && AR[j] > val){
AR[j + 1] = AR[j];
j = j - 1;
}
AR[j + 1] = val;
}
} // end of insertion sort function

The problem is that your vector contains val values, so indexes are in [0, val-1], but within this loop :
for (int i = 1; i <= val; i++)
The last iteration will try to access the element at index val+1, which is out of bounds (it also misses the first element, at index 0)
Change it to :
for (int i = 0; i < val; i++)
And since indexes are of type std::size_t :
for (std::size_t i = 0; i < val; i++)
Note:
Your sort function takes a vector by value, sorting a copy of the vector. You probably want to pass by reference instead :
void Insertion_sort(vector<int>& AR, int n)

Related

How is the pointer (*) making changes in the following code?

The following program is intended to check if a given element is in a given array, indices of array where the element occurs and number of times the element occurs. But, it doesn't give right results. I tried to replace poscount in seqsearch function with *poscount and did further changes for this pointer data type. Then the code works well. Why this is so?
#include <iostream>
using namespace std;
const int SIZE = 100;
void seqsearch(int[], int, int, int[], short);
int main() {
int array[SIZE], indices[SIZE];
int num, value;
short count = 0;
cerr << " Give number of elements in array : ";
cin >> num;
cerr << " Key in the array elements ";
for(int i = 0; i < num; i++) cin >> array[i];
cout << endl;
cerr << " Give the value to be searched : " << endl;
cin >> value;
cout << endl;
seqsearch(array, num, value, indices, count); // void function
if(count >= 0) {
cout << value << " found in array " << count << " times"
<< " at index positions " << endl;
for(int i = 0; i < count; i++) cout << indices[i] << " ";
cout << endl;
} else
cout << value << " not found in array " << endl;
return 0;
}
void seqsearch(int arr[], int size, int elm, int pos[], short poscount) {
int i, item;
poscount = 0;
for(i = 0; i < size; i++) {
if(arr[i] == elm) {
pos[poscount] = i;
poscount = poscount + 1;
}
}
return;
}
The function seqsearch is supposed to return the result in pos and poscount, but the function takes poscount by-value which means that any changes you make to poscount inside the function, will be local to the function and not visible from the call site.
If you change the function to take the argument by-reference, the changes you make inside the function will actually be made to the variable used in the call to the function. Like this:
seqsearch(int arr[], int size, int elm, int pos[], short& poscount) // note short&
The int pos[] does not have the same problem because arrays decay into pointers, so it could have been int* pos instead - and that pointer points at the same array that you passed in at the call site.
Also note that the check after the call will make the program display "found in array" even if it isn't found in the array because the condition checks if count is zero or greater than zero.
if(count >= 0) { // should be if(count > 0) {
Suggestions unrelated to the problem in your question:
When the number of elements is not known at the time you compile your program, prefer to use a container which can grow dynamically, like a std::vector<int>. In your program you have a hardcoded limit of SIZE number of elements, but:
You will rarely use all of them.
You do not check if the user wants to enter more than SIZE elements and your program will gladly try to write out of bounds - which would cause undefined behavior.
Divide the program's subtasks into functions. It'll be easier to search for bugs if you can test each individual function separately.
Check that extracting values from std::cin actually succeeds.
int number;
if(std::cin >> number) { /* success */ } else { /* failure */ }
Check that the values entered makes sense too.
int wanted_container_elements;
if(std::cin >> wanted_container_elements && wanted_container_elements > 0) {
/* success */
} else {
/* failure */
}
poscount (or count in the context of the caller) in your code seems to be expected to be an output parameter.
To modify the passed value you must either have its address (a pointer) or a reference to the value.
Currently you are using "pass-by-value", meaning that poscount is a copy of count.
The original count stays untouched.
My personal favorite would be to return the value instead of using an out-parameter:
short seqsearch(int arr[], int size, int elm, int pos[]) {
int i, item;
short poscount = 0;
for(i = 0; i < size; i++) {
if(arr[i] == elm) {
pos[poscount] = i;
poscount = poscount + 1;
}
}
return poscount;
}
count = seqsearch(array, num, value, indices);
Alternatively you can use a reference to manipulate the out-parameter:
void seqsearch(int arr[], int size, int elm, int pos[], short& poscount) {
int i, item;
poscount = 0;
for(i = 0; i < size; i++) {
if(arr[i] == elm) {
pos[poscount] = i;
poscount = poscount + 1;
}
}
return;
}
seqsearch(array, num, value, indices, count);
And, as you already tried, you can also solve this by passing a pointer to the value:
void seqsearch(int arr[], int size, int elm, int pos[], short* poscount) {
int i, item;
*poscount = 0;
for(i = 0; i < size; i++) {
if(arr[i] == elm) {
pos[*poscount] = i;
*poscount = *poscount + 1;
}
}
return;
}
seqsearch(array, num, value, indices, &count);
When you pass your posscount argument, you pass a copy to the count variable in main, not the variable itself. That's why it works, when you pass it by pointer. You can also pass by reference. https://www.includehelp.com/cpp-tutorial/argument-passing-with-its-types.aspx

Vector equilibrium point(s) function in C++

So I wanted to clean the rust off my C++ skills and thought I'd start with something fairly simple. An equilibrium point in a vector A of size N is a point K, such that: A[0] + A[1] + ... + A[K−1] = A[K+1] + ... + A[N−2] + A[N−1]. The rationale behind the function algorithm is simple: Check each consecutive element of the vector and compare the sum of the elements before said element with the sum of the elements after it and if they are equal, output the index of that element. While it sounds simple (and I imagine that it is) it turned out to be harder to implement in reality. Here's what the code looks like:
#include <iostream>
#include <vector>
using std::cin;
using std::cout;
using std::endl;
void EquilibriumPoint(std::vector<int> &A);
void VectorPrint(std::vector<int> &V);
void main()
{
int input;
std::vector<int> Vect1;
cout << "Input the vector elements" << endl;
while (cin >> input)
Vect1.push_back(input);
VectorPrint(Vect1);
EquilibriumPoint(Vect1);
}
void EquilibriumPoint(std::vector<int> &A)
{
for (int it = 0; it != A.size(); ++it)
{
int lowersum = 0;
int uppersum = 0;
for (int beg = 0; beg != it; ++beg) lowersum += A[beg];
for (int end = it + 1; end != A.size(); ++end) uppersum += A[end];
if (uppersum == lowersum) cout << it;
}
}
void VectorPrint(std::vector<int> &V)
{
for (int i = 0; i != V.size(); ++i)
cout << V[i] << endl;
}
As you can see I threw in a print function also for good measure. The problem is that the program doesn't seem to execute the EquilibriumPoint function. There must be a problem with the logic of the implementation but I can't find it. Do you guys have any suggestions?
cin >> input
always returns true for you - so IMHO you have an endless loop. You need to stop collecting elements at some point, for instance
int input = 1
while (input)
{
cin >> input;
Vect1.push_back(input);
}
Will accept all elements that are not zero, when zero arrives, it will end the vector and run your function.
Or you can first input the number of elements (if you want to include zeros), example:
int count;
cin >> count
for (int i = 0; i < count; ++i)
{
cin >> input;
Vect1.push_back(input);
}
I didn't check the rest of the code, though. One problem at a time.

pass a single row from 2d vector to function

With the help of SO members, the following program successfully converts a static 1D array into a 2D vector by considering below criteria:
Each time an element with value = 0 is encountered, a new row is created. Basically when a 0 is encountered, row value is increased and column value is reset to 0. If a non-zero value is encountered, the row value is maintained and column value is increased.
// declarations
int givenArray[9] = {1, 2, 3, 0, 4, 0, 1, 2, 1};
std::vector<int>::size_type j;
std::vector<int>::size_type i;
vector<vector<int>> my2dArray;
vector<int> dArray;
void calc(vector<int>&, int);
int task;
int sum = 0;
int main() {
for (int i = 0; i < 9;
i++) // iterate through all elements of the given array
{
if (i == 0) // adding the first element
{
my2dArray.resize(my2dArray.size() + 1);
my2dArray.back().push_back(givenArray[i]);
continue;
}
if (givenArray[i] == 0) // re-size if 0 is encountered
{
my2dArray.resize(my2dArray.size() + 1);
}
my2dArray.back().push_back(givenArray[i]);
}
for (std::vector<std::vector<int>>::size_type i = 0; i < my2dArray.size();
i++) {
for (std::vector<int>::size_type j = 0; j < my2dArray[i].size(); j++) {
std::cout << my2dArray[i][j] << ' ';
if (my2dArray[i].size() > 2) {
task = my2dArray[i].size();
calc(my2dArray[i], task);
}
}
std::cout << std::endl;
}
}
void calc(vector<int>& dArray, int task) {
int max = 0;
for (unsigned int j = 0; j < task; j++) {
if (dArray[i] > max)
dArray[i] = max;
}
cout << "\nMax is" << max;
}
However, I want to pass a single row of 2D vector 2dArray to function calc if the number of columns for each row exceeds 2. Function calc aims to find maximum value of all the elements in the passed row. The above program doesn't yield the desired output.
Some improvements:
i and j global variables are not needed, you are declaring the variables of the loops in the loop initialization (ex: for (int i = 0; i < 9; i++), the same for the other loops).
It's better not to used global variables, only when strictly necessary (with careful analysis of why). In this case it's not necessary.
The typedef are for more easy access to inner typedef of the type (ex: size_type).
You were doing the call to calc method in every iteration of the inner loop, and iterating over the same row multiple times, this call should be executed once per row.
Using the size of array givenArray as constant in the code is not recommended, later you could add some elements to the array and forgot to update that constant, it's better to declare a variable and calculated generally (with sizeof).
There is no need to pass the size of the vector to method calc if you are passing the vector.
As recommended earlier it's better to use std::max_element of algorithm header.
If you could use C++11 the givenArray could be converted to an std::vector<int> and maintain the easy initialization.
Code (Tested in GCC 4.9.0)
#include <vector>
#include <iostream>
using namespace std;
typedef std::vector<int> list_t;
typedef std::vector<list_t> list2d_t;
void calc(list_t& dArray, long& actual_max) {
for (unsigned int j = 0; j < dArray.size(); j++) {
if (dArray[j] > actual_max) {
actual_max = dArray[j];
}
}
cout << "Max is " << actual_max << "\n";
}
void calc(list_t& dArray) {
long actual_max = 0;
for (unsigned int j = 0; j < dArray.size(); j++) {
if (dArray[j] > actual_max) {
actual_max = dArray[j];
}
}
cout << "Max is " << actual_max << "\n";
}
int main() {
int givenArray[9] = {1, 2, 3, 0, 4, 0, 1, 2, 1};
int givenArraySize = sizeof(givenArray) / sizeof(givenArray[0]);
list2d_t my2dArray(1);
list_t dArray;
for (int i = 0; i < givenArraySize; i++) {
if (givenArray[i] == 0) {
my2dArray.push_back(list_t());
} else {
my2dArray.back().push_back(givenArray[i]);
}
}
long max = 0;
for (list2d_t::size_type i = 0; i < my2dArray.size(); i++) {
for (list_t::size_type j = 0; j < my2dArray[i].size(); j++) {
std::cout << my2dArray[i][j] << ' ';
}
std::cout << "\n";
if (my2dArray[i].size() > 2) {
// if you need the max of all the elements in rows with size > 2 uncoment bellow and comment other call
// calc(my2dArray[i], max);
calc(my2dArray[i]);
}
}
}
Obtained Output:
1 2 3
Max is 3
4
1 2 1
Max is 2
You have a few problems:
You don't need to loop over j in the main function - your calc function already does this.
Your calc function loops over j, but uses the global variable i when accessing the array.
Your calc function assigns the current max value to the array, rather than assigning the array value to max
Function calc aims to find maximum value of all the elements in the passed row. The above program doesn't yield the desired output.
Instead of writing a function, you could have used std::max_element.
#include <algorithm>
//...
int maxVal = *std::max_element(my2dArray[i].begin(), my2dArray[i].begin() + task);
cout << "\Max is " << maxVal;

recursive algorithm to sum of every element in an array with a value lesser than x

I'm a beginner to c++ and I'm trying to write an recursive algorithm that returns the sum of every element in an array with a value less than x.
Here is my code:
#include <iostream>
using namespace std;
int sumOfElement(int xList[],int x, int lengthOfArray){
int sum = 0;
if (lengthOfArray == 0)
return sum;
else
for (int i=0; i <= lengthOfArray; i++) {
if(xList[i] < x)
return sum + xList[i];
else
sumOfElement(xList,x,lengthOfArray-1);
}
}
int main() {
cout << "Size of Array: ";
int size;
cin >> size;
int *xList = new int[size];
//Inputing array.
cout << "Enter elements of array followed by spaces: ";
for (int i = 0; i<size; i++)
cin >> xList[i];
cout << "Enter the integer value of x: " <<endl;
int limit;
cin >> limit;
cout << "Sum of every element in an array with a value less than x: " << sumOfElement(xList,limit,size) << endl;
return 0;
}
I'm using Visual Studio, while I was running the code, I got this warning: "warning C4715: 'sumOfElement' : not all control paths return a value. " And the program always stop executing when it asks me to enter the integer value for x.
What's wrong with my code?
Your approach here isn't really recursive. The idea with recursion is to consider a base case, and then consider how to reduce the problem at each step until you get to the base case.
For this problem:
The base case is when the length of the array is zero. In this case we return a sum of zero. (Intuitively: if the array is empty then we're adding nothing, giving a sum of zero.)
In order to reduce our array we look at the last element of the array (ie. at lengthOfArray - 1). We process this element: if it's less than x we add it, if it's not then we ignore it. We then get the result of processing the rest of the array by the same means (by calling the same function, but with a different array length), and add our result if applicable.
So, some example code:
int sumOfElement(int xList[], int x, int lengthOfArray){
if (lengthOfArray == 0) {
// base case
return 0;
} else {
int value = xList[lengthOfArray-1];
if (value < x) {
// process the rest of the array and add our result
return value + sumOfElement(xList, x, lengthOfArray - 1);
} else {
// process the rest of the array
return sumOfElement(xList, x, lengthOfArray - 1);
}
}
}
for (int i=0; i <= lengthOfArray; i++)
{
if(xList[i] < x)
return sum + xList[i];
else sumOfElement(xList,x,lengthOfArray-1);
}
You shouldn't have a for-loop, and recursive functions should "return" the deeper call, so
int retVal = 0;
if(xList[lengthOfArray-1] < x)
retval = xList[lengthOfArray-1]
return retVal + sumOfElement(xList,x,lengthOfArray-1);

How to pass vectors between multiple functions?

#include <iostream>
#include <vector>
using namespace std;
class PerformSort
{
public:
const vector<int> * p;
vector<int>& getElements(int);
vector<int>& sortArray(vector<int>&);
void printer(vector<int>&);
}firstSort;
vector<int>& PerformSort::getElements (int num)
{
vector<int> elements(num);
for (int i = 0; i < num; i++)
{
cout << "Enter elements into the array: ";
cin >> elements[i];
}
p = &elements;
return p;
}
vector<int>& PerformSort::sortArray (vector<int>& vector)
{
int holder, min;
for (int i = 0; i < (sizeof(vector) - 1); i++)
{
min = i;
for (int j = (i + 1); j < sizeof(vector); j++)
{
if (vector[j] < vector[min])
{
min = j;
}
}
if (min != i)
{
holder = vector[i];
vector[i] = vector[min];
vector[min] = holder;
}
}
return vector;
}
void PerformSort::printer(vector<int>& vector2)
{
for (int i = 0; i < sizeof(vector2); i++)
{
cout << vector2[i] << " ";
}
}
int main ()
{
int numberOfTimes;
cin >> numberOfTimes;
firstSort.printer(firstSort.sortArray(firstSort.getElements(numberOfTimes)));
return 0;
}
This returns the error: "invalid initialization of reference of type from expression of type". My first approach to create a SelectionSort algorithm was to try passing the vector by value (stupidly). After this I started to use pointers instead, after some research. However, this resulted in the aforementioned error. Declaring everything as constant does not seem to resolve the underlying error, despite how, if I understand things correctly, the error lies with temporary references being passed where constant ones are required. Any thoughts on how I might achieve this passing and returning of vectors? (I come from a Java background and am just beginning C++, so forgive me if I have made any obvious errors with regards to the pointers).
Return it by value:
vector<int> PerformSort::getElements (int num)
{
vector<int> elements(num);
for (int i = 0; i < num; i++)
{
cout << "Enter elements into the array: ";
cin >> elements[i];
}
return elements;
}
This will also let you get rid of p, which is a huge can of worms in its own right.
Finally, I notice that you use sizeof(vector) in quite a few places. This won't give you the number of elements in the vector; use vector.size() instead.
Rename the variable vector to something else:
vector<int>& PerformSort::sortArray (vector<int>& wayBetterName)
&
return wayBetterName;
What urged you to name a variable the same as a type?
There's many more other issues with the code.
You don't need pointers, you don't need the references, plus you're better off just using std::sort.