I want to know why the error appears when the code just gets into the function '
sort'
I made some check points using standard output. So I know where the error occurs.
I use repl.it to build this code
...
/*return pivot function*/
int partition(...){
...
}
void sort(vector<int> array, int left, int right){\
/*********"sort start" string dose not appear in console***********/
cout << "sort start";
// one element in array
if(left == right);
// two elements in array
else if( left +1 == right){
if(array.at(0) > array.at(1)){
int temp;
swap(array.at(0),array.at(1),temp);
}
}
// more then 3 elements in array
else{
int p = partition(array,left,right);
sort(array,left,p-1);
sort(array,p+1,right);
}
}
int main() {
vector<int> array;
array.push_back(1);
array.push_back(2);
array.push_back(3);
array.push_back(4);
cout << "array is ";
for(int i = 0 ; i < array.size(); i++){
cout << array.at(i) << " ";
}
cout << endl;
sort(array,0,array.size()-1);/***************sort is here*************/
cout << "sorting..." << endl;
cout << "array is ";
for(int i = 0 ; i < array.size(); i++){
cout << array.at(i) << " ";
}
return 0;
}
When I run this code console output is
array is 4 3 2 2
terminate called after throwing an instance of 'std::out_of_range'
what(): vector::_M_range_check: __n (which is 18446744073709551615) >=
this->size() (which is 4)
exited, aborted
But what I expected is
array is 4 3 2 2
sorting...
sort start
array is 2 2 3 4
You are trying to access an element at index -1, which, when converted into 64-bit unsigned value, is 18446744073709551615. Live demo: https://wandbox.org/permlink/jAhJZS3ANjkDDOUr.
There are multiple problems with your code and, first of all, you don't show us the definition of your partition and swap. Moreover, your code does not match the provided output (1 2 3 4 vs 4 3 2 2 in the first line).
Anyway, one of the problems is that you don't check for cases where left is higher than right. That can easily happen. Consider that in the very first call of sort, partition returns 0 (pivot position). Then, you call:
sort(array, left, p - 1);
which turns into
sort(array, 0, -1);
That's where negative indexes can be generated.
Related
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int typedNos;
if (cin >> typedNos)
{
vector <int> inputNos{ typedNos };
while (cin >> typedNos)
{
inputNos.push_back(typedNos);
}
for (decltype (inputNos.size()) n = 1; n < inputNos.size(); ++n)
{
cout << inputNos[0] + inputNos[1] << '\t' << inputNos[(2 * n) - 1]
+ inputNos[(2 * n)] << endl;
return 0;
}
}
else
{
cerr << " Wrong input type or no input was typed!" << endl;
//return -1;
}
}
Everything works fine till the output statement in the for loop is reached. The first two pairs of the vector's elements are manually added to account for zero. The rest are to be added automatically. But this only works for the first pair.
So, for example, an input of:
1 2 3 4 5.
Will give you an output of:
3 5.
Instead of 3 5 7 9.
This is where I have an issue. I have seen other methods of solving this problem but my question is why the sequence 2n (even positions) and 2n-1 (odd positions) do not work for the entire vector? Remember this question does not allow me to use iterators. Thanks.
The problem lies in your for-loop. Using return inside a loop will still exit from the current function. Your current function is main, so this ends the program.
I'm not really sure why you think you need 2 * n. It seems you want to iterate over every object, not every second one.
for (std::size_t n = 1; n < inputNos.size(); ++n) {
std::cout << inputNos[n] + inputNos[n-1] << '\t';
}
std::cout << std::endl;
So I've been working on problem 15 from the Project Euler's website , and my solution was working great up until I decided to remove the cout statements I was using for debugging while writing the code. My solution works by generating Pascal's Triangle in a 1D array and finding the element that corresponds to the number of paths in the NxN lattice specified by the user. Here is my program:
#include <iostream>
using namespace std;
//Returns sum of first n natural numbers
int sumOfNaturals(const int n)
{
int sum = 0;
for (int i = 0; i <= n; i++)
{
sum += i;
}
return sum;
}
void latticePascal(const int x, const int y, int &size)
{
int numRows = 0;
int sum = sumOfNaturals(x + y + 1);
numRows = x + y + 1;
//Create array of size (sum of first x + y + 1 natural numbers) to hold all elements in P's T
unsigned long long *pascalsTriangle = new unsigned long long[sum];
size = sum;
//Initialize all elements to 0
for (int i = 0; i < sum; i++)
{
pascalsTriangle[i] = 0;
}
//Initialize top of P's T to 1
pascalsTriangle[0] = 1;
cout << "row 1:\n" << "pascalsTriangle[0] = " << 1 << "\n\n"; // <--------------------------------------------------------------------------------
//Iterate once for each row of P's T that is going to be generated
for (int i = 1; i <= numRows; i++)
{
int counter = 0;
//Initialize end of current row of P's T to 1
pascalsTriangle[sumOfNaturals(i + 1) - 1] = 1;
cout << "row " << i + 1 << endl; // <--------------------------------------------------------------------------------------------------------
//Iterate once for each element of current row of P's T
for (int j = sumOfNaturals(i); j < sumOfNaturals(i + 1); j++)
{
//Current element of P's T is not one of the row's ending 1s
if (j != sumOfNaturals(i) && j != (sumOfNaturals(i + 1)) - 1)
{
pascalsTriangle[j] = pascalsTriangle[sumOfNaturals(i - 1) + counter] + pascalsTriangle[sumOfNaturals(i - 1) + counter + 1];
cout << "pascalsTriangle[" << j << "] = " << pascalsTriangle[j] << '\n'; // <--------------------------------------------------------
counter++;
}
//Current element of P's T is one of the row's ending 1s
else
{
pascalsTriangle[j] = 1;
cout << "pascalsTriangle[" << j << "] = " << pascalsTriangle[j] << '\n'; // <---------------------------------------------------------
}
}
cout << endl;
}
cout << "Number of SE paths in a " << x << "x" << y << " lattice: " << pascalsTriangle[sumOfNaturals(x + y) + (((sumOfNaturals(x + y + 1) - 1) - sumOfNaturals(x + y)) / 2)] << endl;
delete[] pascalsTriangle;
return;
}
int main()
{
int size = 0, dim1 = 0, dim2 = 0;
cout << "Enter dimension 1 for lattice grid: ";
cin >> dim1;
cout << "Enter dimension 2 for lattice grid: ";
cin >> dim2;
latticePascal(dim1, dim2, size);
return 0;
}
The cout statements that seem to be saving my program are marked with commented arrows. It seems to work as long as any of these lines are included. If all of these statements are removed, then the program will print: "Number of SE paths in a " and then hang for a couple of seconds before terminating without printing the answer. I want this program to be as clean as possible and to simply output the answer without having to print the entire contents of the triangle, so it is not working as intended in its current state.
There's a good chance that either the expression to calculate the array index or the one to calculate the array size for allocation causes undefined behaviour, for example, a stack overflow.
Because the visibility of this undefined behaviour to you is not defined the program can work as you intended or it can do something else - which could explain why it works with one compiler but not another.
You could use a vector with vector::resize() and vector::at() instead of an array with new and [] to get some improved information in the case that the program aborts before writing or flushing all of its output due to an invalid memory access.
If the problem is due to an invalid index being used then vector::at() will raise an exception which you won't catch and many debuggers will stop when they find this pair of factors together and they'll help you to inspect the point in the program where the problem occurred and key facts like which index you were trying to access and the contents of the variables.
They'll typically show you more "stack frames" than you expect but some are internal details of how the system manages uncaught exceptions and you should expect that the debugger helps you to find the stack frame relevant to your problem evolving so you can inspect the context of that one.
Your program works well with g++ on Linux:
$ g++ -o main pascal.cpp
$ ./main
Enter dimension 1 for lattice grid: 3
Enter dimension 2 for lattice grid: 4
Number of SE paths in a 3x4 lattice: 35
There's got to be something else since your cout statements have no side effects.
Here's an idea on how to debug this: open 2 visual studio instances, one will have the version without the cout statements, and the other one will have the version with them. Simply do a step by step debug to find the first difference between them. My guess is that you will realize that the cout statements have nothing to do with the error.
attempting to code a drill from C++ study book, "Write a program that consists of a while-loop that (each time around the loop) reads in two ints and then prints them. Exit the program when a terminating '|' is entered."
i coded the following:
#include "C:\Users\Erez\Documents\Dev C++ Projects\std_lib_facilities.h"
int main(){
vector<int> v;
int value {0};
int i {1};
while (cin >> value)
{
v.push_back(value);
if (i % 2 == 0) { //using the % modulo to cout couples.
cout << v[i] << '\t' << v[i-1] << "\n"; // cout i + (i-1)
}
++i;
}
}
feeding two values separated by either space or line, i get this error:
4
5
terminate called after throwing an instance of 'Range_error'
what(): Range error: 2
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
Would appreciate any help :)
Indices into vectors, arrays, etc. start at index 0
You are initializing your index to 1 and incrementing from there.
Thus, v[i] is referring to the value after the last one you pushed. This is an attempt to access something out of bounds and it is causing your program to crash.
Your statement of:
if (i % 2 == 0){
//
}
becomes true on second iteration inside your while loop and the statement of:
cout << v[i] << '\t' << v[i-1] << "\n"; // cout i + (i-1)
gets executed. The culprit here is v[i] which is actually v[2]. By now your vector only has two elements: v[0] and v[1], meaning that with the v[2] you are trying to read out of bounds. Rethink the logic inside your while statement and initialize the i counter to 0 rather than 1 to begin with. If you are trying to print out even vector elements then it should be:
if (v[i] % 2 == 0)
I am new at programming at c++, and when I run this, it compiles successfully and outputs the elements of the array but I get an error that says "vector subscript out of range". What is wrong with this code? I looked at some other questions and it did not seem like any of the others had similar examples of vectors.
#include <iostream>
#include <vector>
#include <random>
#include <time.h>
using namespace std;
int main() {
srand(time(NULL));
int arraysize;
cout << "Enter the size of your array:" << endl;
cin >> arraysize;
vector<int> numbers(arraysize);
vector<int>::size_type sizecheck = numbers.size();
cout << "This is the unsorted array:" << endl;
for (int z = 0; numbers[z] < sizecheck; z++)
{
numbers[z] = rand() % 10 + 1;
cout << numbers[z] << endl;
}
return 0;
}
Your code actually would be an infinite loop given infinite memory, however, since there is a finite amount of memory allocated for your vector, it exhibits undefined behavior. numbers will value initialize (set each element to 0), meaning that the condition is always going to be 0 < sizecheck. Once z reaches the amount of elements in your vector, you exceed the array bounds and wander into undefined behavior land.
Your IDE or whatever you're using already caught the error, but you can use the safer variant, at() instead of operator[]. This will throw an exception and provide useful information. For example:
for (int z = 0; numbers.at(z) < sizecheck; z++)
{
numbers.at(z) = rand() % 10 + 1;
cout << z << " " << numbers.at(z) << endl;
}
0 2
1 8
2 10
3 9
4 8
5 2
6 3
7 4
8 4
9 2
terminate called after throwing an instance of 'std::out_of_range'
what(): vector::_M_range_check: __n (which is 10) >= this->size() (which is 10)
As stated in the comments, what you probably meant to do was z < sizecheck, although you should make z of type std::vector<int>::size_type just to be safe.
#remyabel has given you the absolutely correct answer, but in addition to that you should consider using an iteratorrather than an indexed for loop when looping over standard components like vector.
e.g.
vector<int>::iterator it;
for(it = numbers.begin(); it != numbers.end(); ++it)
{
*it = rand() % 10 + 1;
cout << *it << endl;
}
Note: this is only suitable if you are changing the number of elements in the vector as you iterate, as is happening in this case. If you add or remove elements during the iteration you may invalidate your iterator.
In the following code I'm trying to find the frequencies of the rows in fileA which have the same value on the second column. (each row has two column and both are integers.) Sample of fileA:
1 22
8 3
9 3
I have to write the output in fileB like this:
22 1
3 2
Because element 22 has been repeated once in second column(and 3 repeated 2 times.)
fileA is very large(30G). And there are 41,000,000 elements in it(in other words, fileB has 41,000,000) rows. This is the code that I wrote:
void function(){
unsigned long int size = 41000000;
int* inDeg = new int[size];
for(int i=0 ; i<size; i++)
{
inDeg[i] = 0;
}
ifstream input;
input.open("/home/fileA");
ofstream output;
output.open("/home/fileB");
int a,b;
while(!input.eof())
{
input>>a>>b;
inDeg[b]++; //<------getting error here.
}
input.close();
for(int i=0 ; i<size; i++)
{
output<<i<<"\t"<<inDeg[i]<<endl;
}
output.close();
delete[] inDeg;
}
I'm facing segmentation fault error on the second line of the while loop. On the 547387th iteration. I have already assigned 600M to the stack memory based on this. I'm using gcc 4.8.2 (on Mint17 x86_64).
Solved
I analysed fileA thoroughly. The reason of the problem as hyde mentioned wasn't with hardware. Segfault reason was wrong indexing. Changing the size to 61,500,000 solved my problem.
In the statement:
while(!input.eof())
{
input>>a>>b;
inDeg[b]++;
}
Is b the index of your array?
When you read in the values:
1 22
You are discarding the 1 and incrementing the value at slot 22 in your array.
You should check the range of b before incrementing the value at inDeg[b]:
while (input >> a >> b)
{
if ((b >= 0) && (b < size))
{
int c = inDeg[b];
++c;
inDeg[b] = c;
}
else
{
std::cerr << "Index out of range: " << b << "\n";
}
}
You are allocating a too huge array in to the heap. It´s a memory thing, your heap cant take that much space.
You should split your in and output in smaller parts, so at example create a for loop which goes every time 100k , deletes them and then does the next 100k.
in such cases try a exception handling, this is a example snippet how to manage exception checking for too huge arrays:
int ii;
double *ptr[5000000];
try
{
for( ii=0; ii < 5000000; ii++)
{
ptr[ii] = new double[5000000];
}
}
catch ( bad_alloc &memmoryAllocationException )
{
cout << "Error on loop number: " << ii << endl;
cout << "Memory allocation exception occurred: "
<< memmoryAllocationException.what()
<< endl;
}
catch(...)
}
cout << "Unrecognized exception" << endl;
{