I am getting a Segmentation Fault with my For loops - c++

I keep getting a segmentation fault error in my code
Header
#ifndef DUALSTK
#define DUALSTK
#include <deque>
using namespace std;
enum stackNumber {One, Two};
template <typename T>
class dualStack {
public:
// constructor. set counts to 0
dualStack() : dualStackElements(20, 0) {}
void push(const T& item, stackNumber n);
void pop(stackNumber n);
T& top(stackNumber n);
//const T& top(stackNumber n) const;
bool empty(stackNumber n) const;
int size(stackNumber n) const;
int getCount1() const {return count1;}
int getCount2() const {return count2;}
private:
deque<T> dualStackElements;
int count1, count2;
};
#endif // DUALSTK
main.cpp
#include <iostream>
#include <deque>
#include "dualstk.h"
using namespace std;
template <typename T>
T& dualStack<T>::top(stackNumber n) {
int num = 0;
if (n == 0) {
num = count1 - 1;
return num;
}
if (n == 1) {
num = 20 - count2;
return num;
}
}
template <typename T>
void dualStack<T>::push(const T& item, stackNumber n) {
if (n == 0) {
count1++;
dualStackElements[top(One)] = item;
}
if (n == 1) {
count2++;
dualStackElements[top(Two)] = item;
}
}
template <typename T>
void dualStack<T>::pop(stackNumber n) {
int item = 0;
int item2 = 0;
if (n == 0) {
item = dualStackElements[top(One)];
cout << item << " ";
count1--;
}
if (n == 1) {
item2 = dualStackElements[top(Two)];
cout << item2 << " ";
count2--;
}
}
template <typename T>
bool dualStack<T>::empty(stackNumber n) const {
return 1;
}
int main() {
dualStack<int> stack;
for(int i = 1; i < 21; i++) {
if(i % 2 == 0) {
stack.push(i, One);
}
else {
cout << i;
stack.push(i, Two);
}
}
cout << endl;
for (int j = 0; j < 10; j++)
stack.pop(One);
cout << endl;
for (int i = 0; i < 10; i++)
stack.pop(Two);
cout << endl;
cout << stack.getCount2();
cout << stack.getCount1();
cout << endl;
cout << "\n" << stack.top(One);
cout << stack.top(Two) << endl;
return 0;
}
Whenever I have one loop for my stack.pop it will work fine
but if I do a for loop right after I use one to do stack.pop it wont work
I am not sure what I did wrong to this
for (int j = 0; j < 10; j++)
stack.pop(One);
for (int i = 0; i < 10; i++)
stack.pop(Two);

function top() returns reference to local variable ‘num’. Its storage is on stack so the value would be modified when the function returns and then you use it as the index into dualStackElements. This may lead to access to invalid memory address.

I think you are misunderstanding what this does (or I misunderstood your code):
dualStackElements[top(One)] = item;
you have not declared an array of dualStackElements
Better to declare two dequeues instead.
deque<T> dualStackElementsOne;
deque<T> dualStackElementsTwo;

Your Top method needs some error checking. What if count1 is 0 (or count2 > 20)? You'd return a negative value and then use it as an index to your deque. And remove the return by reference!

top() method returns a reference to local variable num which was freed after the method call. But different OS have different limits on accessing illegal memory, sometimes, it is just OK in Linux.
In your constructor, there is no initializing operations for fields: count1, count2. The program always returns "Segmentation fault;" if I comment out "count1=count2=0;" in my modified constructor.
In order to get the stable result for a program, you should do a clean before a make. I don't know exactly why, but it did happen in my test run.

Related

Getting out of range exception when using while loop with vector in c++

I am getting an out of range exception with my while loop in my code.
I have tried to use an Array instead and the error does not occur with the same loop structure. I am confused why this would happen. I believe that the savedValue <= value[rank.at(current-1)]) statement is what is causing the error.
int suffixArray::size;
std::vector<int> suffixArray::rank;
int main( int argc, char* argv[]) {
std:: string test = "BANANA$";
suffixArray testString (test);
return 0;
}
#include <iostream>
#include <vector>
class suffixArray{
public: static int size;
public: static std::vector<int> rank;
public: suffixArray(std:: string concatenated ){
size =(int) concatenated.length();
std:: cout << size << std:: endl;
rank.resize(7);
char *suffixPointers[concatenated.length()];
int value[concatenated.length()];
for(int i =0; i <= size-1; i++){
suffixPointers[i] = &concatenated[i];
value[i] = (int)concatenated[i];
}
std::cout << "[";
for(int i = 0; i<= size-1; i++){
std::cout <<value[i] << " ";
}
std::cout << "]"<< std:: endl;
for(int i = 0; i<=size -1; i++){
if(i == 0){
rank.assign(i,i);
}
else if(value[i] > value[i-1]){
rank.assign(i,i);
}else{
int current =i;
int savedValue = value[i];
int prevSavedRank;
while(current-1 >= 0 && savedValue <= value[rank.at(current-1)]){
prevSavedRank= rank.at(current-1);
rank.assign(current-1, i);
rank.assign(current, prevSavedRank);
current--;
}
}
}
}
};
Adding more logging into your program reveals the problem: you rank.assign(0,0) - the first 0 specifies the new vector length, so this call removes all the elements in the vector (see std::vector::assign docs at cppreference) then call rank.at(0): 0 is not a valid index into an empty vector, so std::out_of_range.
You'll have to rethink your logic.
Program with extra logging:
#include <iostream>
#include <vector>
template <typename T>
struct Vector : std::vector<T>
{
void assign(size_t count, const T& value)
{
std::cout << "assign(count " << count << ", " << value << ")\n";
std::vector<T>::assign(count, value);
}
const T& at(size_t pos) const
{
std::cout << "at(" << pos << ")\n";
return std::vector<T>::at(pos);
}
};
class suffixArray{
public: static int size;
public: static Vector<int> rank;
public: suffixArray(std:: string concatenated ){
size =(int) concatenated.length();
std:: cout << size << std:: endl;
rank.resize(7);
char *suffixPointers[concatenated.length()];
int value[concatenated.length()];
for(int i =0; i <= size-1; i++){
suffixPointers[i] = &concatenated[i];
value[i] = (int)concatenated[i];
}
std::cout << "[";
for(int i = 0; i<= size-1; i++){
std::cout <<value[i] << " ";
}
std::cout << "]"<< std:: endl;
for(int i = 0; i<=size -1; i++){
if(i == 0){
rank.assign(i,i);
}
else if(value[i] > value[i-1]){
rank.assign(i,i);
}else{
int current =i;
int savedValue = value[i];
int prevSavedRank;
while(current-1 >= 0 && savedValue <= value[rank.at(current-1)]){
prevSavedRank= rank.at(current-1);
rank.assign(current-1, i);
rank.assign(current, prevSavedRank);
current--;
}
}
}
}
};
int suffixArray::size;
Vector<int> suffixArray::rank;
int main( int argc, char* argv[]) {
std:: string test = "BANANA$";
suffixArray testString (test);
}
Output:
7
[66 65 78 65 78 65 36 ]
assign(count 0, 0)
at(0)
terminate called after throwing an instance of 'std::out_of_range'
what(): vector::_M_range_check: __n (which is 0) >= this->size() (which is 0)
I have tried to use an Array instead and the error does not occur with the same loop structure.
std::array and C-style arrays (T[]) are fixed sized containers, lacking an equivalent of the std::vector::assign you're using to resize your vector, so your program must have been modified quite heavily - not just a clean substitution of an array.

std::vector out of range for min-heap: C++

I've neglected to work on this code (or any other coding projects) for a while, so while I know what is basically wrong with the code, I've been having a hard time finding exactly where the vector is going out of range. I've been running gdb on it all morning to no avail. I'm trying to make a min-heap out of a vector "theData" in C++.
#include <iostream>
#include <vector>
#include <algorithm>
using std::vector;
using std::cin;
using std::cout;
using std::swap;
using std::pair;
using std::make_pair;
class HeapBuilder {
private:
vector<int> data_;
vector< pair<int, int> > swaps_;
void WriteResponse() const {
cout << swaps_.size() << "\n";
for (int i = 0; i < swaps_.size(); ++i) {
cout << swaps_[i].first << " " << swaps_[i].second << "\n";
}
}
void ReadData() {
int n;
cin >> n;
data_.resize(n);
for(int i = 0; i < n; ++i)
cin >> data_[i];
}
void makeMinHeap(vector<int> &theData, int i, int n) {
int minIndex;
int left = 2*i;
int right = 2*i + 1;
if (left < n && theData.at(left) < theData.at(i)) {
minIndex = left;
}
else if (right < n && theData.at(right) < theData.at(i)) {
minIndex = right;
}
if (minIndex != i) {
swap(theData.at(i), theData.at(minIndex));
swaps_.push_back(make_pair(i, minIndex));
makeMinHeap(theData, minIndex, n);
}
}
void GenerateSwaps() {
swaps_.clear();
int size = data_.size();
for (int i = (size/2); i >= 0; i--) {
makeMinHeap(data_, i, size);
}
}
public:
void Solve() {
ReadData();
GenerateSwaps();
WriteResponse();
}
};
int main() {
std::ios_base::sync_with_stdio(false);
HeapBuilder heap_builder;
heap_builder.Solve();
return 0;
}
You are not putting in a check for minIndex.
Look what happens when your left<=n and right <=n both fails, most likely when the whole recursion is about to stop, since you just check
minIndex != i
// ^-- default each time is garbage which in case last>n && right>n leaves it garbage
// hence when it comes to
if(minIndex!=i){
// It's actually true where it was suppose to break out n thus throws out_of_range
}
Quick n easy solution would be to add a flagcheck
bool flagcheck = false;
if(){ flagcheck = true; }
else if(){ flagcheck = true; }
if(minIndex!=i && flagcheck){}

Vector elements are not swapped in partition algorithm.

Problem is from the Elements of Programming Interviews Book (2012).
Problem 6.1 pg 53: "Write a functions that take an array A (I used vector) and an index i into A, and rearranges the elements such that all elements less than A[i] appear first, followed by elements equal to A[i], followed by elements greater than A[i]. Your algorithm should have O(1) space complexity and O(|A|) time complexity.
My code doesn't do anything to the vector.
#include <iostream>
#include <vector>
using namespace std;
template <typename T>
void swapit(vector<T> v, int i, int j)
{
T temp;
temp = v[i];
v[i] = v[j];
v[j] = temp;
}
template <typename T>
void dutch_flag_partition(vector<T> &v, int pivotindex)
{
T pivot = v[pivotindex];
int lower = 0;
int equals = 0;
int larger = v.size() - 1;
while(equals <= larger)
{
cout << equals << " " << larger<< endl;
if(v[equals] < pivot)
{
swapit(v, lower++, equals++);
}
else if(v[equals] == pivot)
{
++equals;
}
else
{
swapit(v, equals, larger--);
}
}
}
int main()
{
int arr[] = {1,11,3,5,3,10,0,22,50,33,4,22,23,100,9};
vector<int> v (arr, arr + sizeof(arr)/sizeof(arr[0]));
dutch_flag_partition(v, 5);
for(int i = 0; i < v.size(); ++i)
{
cout << v[i] << " ";
}
cout << endl;
return 0;
}
void swapit(vector<T> v, int i, int j) { ... }
This does not modify the vector you passed in. Instead, it creates a copy for this function. You probably want to use a reference:
void swapit(vector<T> & v, int i, int j) { ... }

How to optimize random sort algorithm?

Here is some random sort program I wrote in C++. It works pretty fine for 10 elements or so. But for 15 elements it works so slow I can't even wait enough to get the result. Is there some way to optimize random sort algorithm?
Here's my code:
// randomsort.h
#ifndef RANDOMSORT_H
#define RANDOMSORT_H
#include <stdlib.h>
#include <time.h>
class RandomSort
{
private:
template <class T>
static bool isOrdered(T*, int);
public:
template <class T>
static int sort(T*, int);
};
template <class T>
bool RandomSort::isOrdered(T* arr, int size)
{
for(int i = 1; i < size; i++)
{
if(arr[i-1] > arr[i])
{
return false;
}
}
return true;
}
template <class T>
int RandomSort::sort(T* arr, int size)
{
int stepAmount = 0;
srand(time(NULL));
while(!isOrdered(arr, size))
{
int i = rand() % size;
int j = rand() % size;
std::swap(arr[i], arr[j]);
stepAmount++;
}
return stepAmount;
}
#endif // RANDOMSORT_H
And main.cpp file
// main.cpp
#include <iostream>
#include "randomsort.h"
int main()
{
int size;
std::cout << "Enter amount of elements to sort: ";
std::cin >> size;
std::cout << std::endl;
int arr[size];
for(int i = 0; i < size; i++)
{
arr[i] = (rand() % (size * 10));
}
std::cout << "Input array: " << std::endl;
for(int i = 0; i < size; i++)
std::cout << arr[i] << ' ';
std::cout << std::endl << std::endl;
int stepAmount = RandomSort::sort(arr, size);
std::cout << "Output array: " << std::endl;
for(int i = 0; i < size; i++)
std::cout << arr[i] << ' ';
std::cout << std::endl << std::endl;
std::cout << "Number of steps: " << stepAmount;
return 0;
}
Any suggestions?
Your code is completely random. So it can swap when it should not. An easy fix would be to swap only if you need it.
int i = rand() % size;
int j = rand() % size;
// to know which should be first
if (i > j)
std::swap(i, j);
if (arr[i] > arr[j])
std::swap(arr[i], arr[j]);
Your array probably will not be sorted immediately, so you could also test if it is sorted only every five steps (for example) instead of every step.
But i think the most important is, you should not expect good performances from such an algorithm.

Private function for operator overload

I am learning about operator overloading in C++. To try it out, I overloaded the [] operator to print the value at the index given. The code worked when I defined the operator overload member function as public.
However when I tried to do the same thing by defining the overload method as private, the code does not work. It does not even enter the operator overload method and skips it completely.
Can somebody please explain to me what am I doing wrong? Do operator overload methods have to be public only?
Here is my code:-
#pragma once
class NArray
{
public:
NArray(int size=100);
int getValueAt(int index);
~NArray();
void test(int index);
//int operator[](int index) const;
private:
int sizeOfArray;
int array[100];
int operator[](int index) const;
};
#include "NArray.h"
#include <iostream>
using namespace std;
NArray::NArray(int size)
{
if (size > 0 && size <=100)
sizeOfArray = size;
else
sizeOfArray = 100;
for (int i = 0; i < sizeOfArray; i++)
{
array[i] = i;
}
}
int NArray::getValueAt(int index)
{
if (index > 0 && index <sizeOfArray)
{
return array[index];
}
else
{
return -1;
}
}
int NArray::operator[](int index)const
{
if (index > sizeOfArray || index < 0)
{
cout << "Index out of bounds" << endl;
return -1;
}
else
{
cout << array[index] << endl;
return array[index];
}
}
void NArray::test(int index)
{
array[index];
}
NArray::~NArray()
{
}
#include <iostream>
#include "NArray.h"
using namespace std;
int main()
{
int size = 0;
int index = 0;
cout << "Enter Array Size:" << endl;
cin >> size;
NArray arr(size);
cout << "Enter Index:" << endl;
cin >> index;
//This works for the public operator method
//arr[index];
//This does not
arr.test(index);
getchar();
return 0;
}
Thanks in advance.
test is not using NArray::operator [], it is accessing array directly. Try changing array[index]; to (*this)[index]; inside of NArray::test, and make it const while you're at it since it's not modifying anything:
void test(int index) const;
// ...
void NArray::test(int index) const
{
(*this)[index];
}
Also, you have a bug in operator[] – if (index > sizeOfArray || index < 0) should be if (index >= sizeOfArray || index < 0).