Segmentation Fault Passing Reference as Function Parameter - c++

With this block of code, I'm getting a segmentation fault as I try to pass the stack references to the transferStacks() method. Any help on understanding why this is would be helpful!
I could just get rid of the helper method and it should work, but I'm trying to understand conceptually.
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
#include <stack>
using namespace std;
void transferStacks(stack<int> & s1, stack<int> & s2){
if (s1.empty()){
for (int i = 0; i < s2.size(); i++){
int element = s2.top();
s1.push(element);
s2.pop();
}
}
}
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
int queries = 0;
cin>>queries;
stack <int> newestOnTop;
stack <int> oldestOnTop;
while (queries!=0){
int type = 0;
cin >> type;
int input = 0;
if (type == 1){ //enqueue
cin>>input;
newestOnTop.push(input);
}
else if (type == 2){ //dequeue
transferStacks(newestOnTop, oldestOnTop);
oldestOnTop.pop();
}
else if (type == 3){ //peek
transferStacks(newestOnTop, oldestOnTop);
cout<<oldestOnTop.top()<<endl;
}
queries--;
}
return 0;
}
Segmentation Fault

You appear to believe that this code will copy s2 to s1:
for (int i = 0; i < s2.size(); i++){
int element = s2.top();
s1.push(element);
s2.pop();
}
But it will not: if before the loop s2 contains 3 elements, only the first 2 will be copied (and generally, only the first half will be copied).
In addition, your transfer function transfers from s2 to s1, but the way you call it implies that you intended the opposite: to transfer from s1 to s2. Current code would leave oldestOnTop empty, which will then result in a crash when you use oldestOnTop.top() or oldestOnTop.pop().

Related

Segmentation fault while returning from function in c++

I using stringstream for parsing string, however it is unexpectedly giving segmentation fault while exiting from function.
bool check_if_condition(int a)
{
string polygonString1="19.922379 51.666267 19.922381 51.665595 19.921547 51.665705 19.921218 51.665753 19.920787 51.665815 19.919753 51.665960 19.919952 51.666897 19.920395 51.666826 19.920532 51.667150 19.920830 51.667748 19.920989 51.667905 19.921690 51.667906 19.922141 51.662866 19.922855 51.668696 19.922664 51.668237 19.922610 51.668025 19.922464 51.667451 19.922355 51.666732 19.922379 51.666267";
double buf1; // Have a buffer string
stringstream ssPolygonString1(polygonString1); // Insert the string into a stream
double polygon1[2]; // Create vector to hold our words
int iterPoly1=0;
while (ssPolygonString1 >> buf1)
{
polygon1[iterPoly1]=(buf1);
cout<<"buf1="<<buf1<<"\n";
iterPoly1++;
}
ssPolygonString1.str("");
cout<<"Return true";
return true;
}
main()
{
check_if_condition(1);
}
Can someone please help me understand what is wrong with the function call?
I am using c++11
I ran it on https://www.tutorialspoint.com/compile_cpp11_online.php, it is giving me Bus error (core dumped)
I assume when you say double polygon1[2] you want to create a vector by your comment.
If you use a vector your code will work.
Also when you use a vector make sure you use vector.push_back();
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
using namespace std;
bool check_if_condition(int a)
{
string polygonString1 = "19.922379 51.666267 19.922381 51.665595 19.921547 51.665705 19.921218 51.665753 19.920787 51.665815 19.919753 51.665960 19.919952 51.666897 19.920395 51.666826 19.920532 51.667150 19.920830 51.667748 19.920989 51.667905 19.921690 51.667906 19.922141 51.662866 19.922855 51.668696 19.922664 51.668237 19.922610 51.668025 19.922464 51.667451 19.922355 51.666732 19.922379 51.666267";
double buf1; // Have a buffer string
stringstream ssPolygonString1(polygonString1); // Insert the string into a stream
vector<double> polygon1; // Create vector to hold our words
int iterPoly1 = 0;
while (ssPolygonString1 >> buf1)
{
//polygon1[iterPoly1] = (buf1);
polygon1.push_back(buf1); // Add buf1 to vector.
cout << "buf1=" << buf1 << "\n";
iterPoly1++;
}
ssPolygonString1.str("");
//Print vector to show it works!
for (int i = 0; i < polygon1.size(); i++)
{
cout << polygon1.at(i) << endl;
}
cout << "Return true";
return true;
}
int main()
{
check_if_condition(1);
system("pause");
return 0;
}
The error is in the line:
polygon1[iterPoly1]=(buf1);
because the length of vector is 2 and iterPoly is going above 2. So behaviour is unexpected.

Unable to manually free memory from queue of arrays

#ifndef UNICODE
#define UNICODE
#endif
#include <iostream>
#include <Windows.h>
#include <queue>
using namespace std;
void addSomeContent(queue<TCHAR*> &output)
{
TCHAR* buffer;
for(int i=0; i < 10000; i++)
buffer = new TCHAR[1000];
}
int main()
{
queue<TCHAR*> foo;
char sign;
beginning:
addSomeContent(foo);
while (!foo.empty())
{
delete [] foo.front();
foo.pop();
}
wcout<<TEXT("Press y to repeat\n");
cin>>sign;
if(sign == 'y' || sign == 'Y') goto beginning;
return 0;
}
Each iteration of this program uses up 20MB of RAM. Why is it not dispatched by this instruction?
while (!foo.empty())
{
delete [] foo.front();
foo.pop();
}
Perhaps it's because while you pass the reference of foo to addSomeContent, and addSomeContent uses it as the variable named output, addSomeContent is allocating all kinds of memory but never placing those allocations in output, so back in main, foo is empty.
At SO we want to be helpful but we really want people to try to help themselves first. This would be a simple problem for you to have spotted on your own if you have done a little debugging before you posted.
You're trying to delete[] memory manually. This is always bad. Use std::queue<std::vector<TCHAR>> instead. Also, goto? This is bad and you should feel bad.
If you want to add an item to the queue, you need to call a member function on it.
The following code might actually function and might not drive anyone looking at it to insanity.
void addSomeContent(std::queue<std::vector<TCHAR>> &output)
{
for(int i=0; i < 10000; i++)
queue.push_back(std::vector<TCHAR>(1000));
}
int recursive_main() {
std::queue<std::vector<TCHAR>> foo;
addSomeContent(foo);
while(!foo.empty()) foo.pop(); // no need to delete
std::wcout << L"Press y to repeat\n";
char sign;
std::cin >> sign;
if (sign == 'y' || sign == 'Y') return recursive_main();
return 0;
}
int main()
{
return recursive_main();
}

C++, using stack.h read a string, then display it in reverse

For my current assignment, I have to use the following header file,
#ifndef STACK_H
#define STACK_H
template <class T, int n>
class STACK
{
private:
T a[n];
int counter;
public:
void MakeStack() {
counter = 0;
}
bool FullStack() {
return (counter == n) ? true : false ;
}
bool EmptyStack() {
return (counter == 0) ? true : false ;
}
void PushStack(T x) {
a[counter] = x;
counter++;
}
T PopStack() {
counter--;
return a[counter];
}
};
#endif
To write a program that will take a sentence, store it into the "stack", and then display it in reverse, and I have to allow the user to repeat this process as much as they want. The thing is, I am NOT allowed to use arrays (otherwise I wouldn't need help with this), and am finding myself stumped.
To give an idea of what I am attempting, here is my code as of posting, which obviously does not work fully but is simply meant to give an idea of the assignment.
#include <iostream>
#include <cstring>
#include <ctime>
#include "STACK.h"
using namespace std;
int main(void)
{
auto time_t a;
auto STACK<char, 256> s;
auto string curStr;
auto int i;
// Displays the current time and date
time(&a);
cout << "Today is " << ctime(&a) << endl;
s.MakeStack();
cin >> curStr;
i = 0;
do
{
s.PushStack(curStr[i]);
i++;
} while (s.FullStack() == false);
do
{
cout << s.PopStack();
} while (s.EmptyStack() == false);
return 0;
} // end of "main"
UPDATE
This is my code currently
#include <iostream>
#include <string>
#include <ctime>
#include "STACK.h"
using namespace std;
time_t a;
STACK<char, 256> s;
string curStr;
int i;
int n;
// Displays the current time and date
time(&a);
cout << "Today is " << ctime(&a) << endl;
s.MakeStack();
getline(cin, curStr);
i = 0;
n = curStr.size();
do
{
s.PushStack(curStr[i++]);
i++;
}while(i < n);
do
{
cout << s.PopStack();
}while( !(s.EmptyStack()) );
return 0;
You're on the right track, but you shouldn't be looping until the stack is full -- there are no guarantees curStr consists of at least 256 characters. Instead, loop like as follows...
int n = curStr.size();
do {
s.PushStack(curStr[i++]);
} while (i < n);
Now, you should really not write <bool-expr> == false or <bool-expr> == true... instead, merely write !<bool-expr> and <bool-expr>, respectively. You don't need all of your auto storage specifiers on the local variables, either. Your professor should also look into using the constructor rather than using MakeStack.
edit: It appears you had some trouble translating my code. You only need to i++ once per loop -- this increments our position in the string. As you are doing it now, you are actually incrementing the position twice and thus only pushing every other character.
Use a linked list instead of array in stack.
In the linked list, always store the tail pointer of your list's last node. Each node maintains a reference to your prev node.
A <--- B <---- C (tail)
push:
A <--- B <---- C <---- D (tail)
pop:
A <--- B <---- C (tail)
// D is popped out
when the tail == null, you know it is an empty stack

Code Crashes Immediately After Running

Even at the bare minimum of 10 numbers to input, I get no errors but my code crashes immediately on running. I was also wondering, what should I do if I have a question similar to another question that I've already asked, but on another new problem?
#include <iostream>
#include <cmath>
#include <fstream>
#include <cstdlib>
#include <vector>
using namespace std;
int primer(int max);
int main()
{
primer(5);
system("pause");
return 0;
}
int primer(int max){
vector<int> a;
a[1]=2;
for (int i=2;i<=max;i++){
bool prime=true;
for (int ii=0;ii<a.size();ii++) {
if (i/a[ii]==floor(i/a[ii])) {
prime=false;
}
}
if (prime==true) {
a.push_back(i);
}
}
for (int iii=0;iii<=a.size();iii++) {
cout << a[iii] << endl;
}
}
I get no errors but the compiled code crashes immediately.
I changed it to
#include <iostream>
#include <cmath>
#include <fstream>
#include <cstdlib>
#include <vector>
using namespace std;
int primer(int max);
int main()
{
primer(5);
system("pause");
return 0;
}
int primer(int max){
vector<int> a;
a.push_back(2);
for (double i=2;i<=max;i++){
bool prime=true;
for (int ii=0;ii<a.size();ii++) {
if (i/a[ii]==floor(i/a[ii])) {
prime=false;
}
}
if (prime) {
a.push_back(i);
}
}
for (int iii=0;iii<=a.size();iii++) {
cout << a[iii] << endl;
return a.size();
}
}
I addressed all of your problems. It still returns no errors and still crashes.
What makes you think you can do this?
vector<int> a;
a[1]=2;
vector<int> a;
a[1]=2;
You can't access a[1] until you've reserved space for it. You should probably use a.push_back(2) to append 2 to the end of a.
You have declared primer to return int, yet it returns nothing. Either make it void or return the number of primes.
i/a[ii]==floor(i/a[ii]) isn't going to do what you expect. i/a[ii] performs integer division. You should cast i to double before dividing.
if (prime==true) can be changed to simply if (prime), no need to compare a boolean to true.
Please improve your coding style. Use proper indentation and more commonly used variable names: i, j, k instead of i, ii, iii.
Here is another bug:
for (int iii=0;iii<=a.size();iii++) {
cout << a[iii] << endl;
return a.size();
}
My understanding is that you can only return once from a function, main included. The execution will not loop here because of the return statement.
Did you really want a return statement inside a for loop?

How to capture a string into variable in a recursive function?

I tried to print all the possible combination of members of several vectors. Why
the function below doesn't return the string as I expected?
#include <iostream>
#include <vector>
#include <fstream>
#include <sstream>
using namespace std;
string EnumAll(const vector<vector<string> > &allVecs, size_t vecIndex, string
strSoFar)
{
string ResultString;
if (vecIndex >= allVecs.size())
{
//cout << strSoFar << endl;
ResultString = strSoFar;
//return ResultString;
}
for (size_t i=0; i<allVecs[vecIndex].size(); i++) {
strSoFar=EnumAll(allVecs, vecIndex+1, strSoFar+allVecs[vecIndex][i]);
}
ResultString = strSoFar; // Updated but still doesn't return the string.
return ResultString;
}
int main ( int arg_count, char *arg_vec[] ) {
vector <string> Vec1;
Vec1.push_back("T");
Vec1.push_back("C");
Vec1.push_back("A");
vector <string> Vec2;
Vec2.push_back("C");
Vec2.push_back("G");
Vec2.push_back("A");
vector <string> Vec3;
Vec3.push_back("C");
Vec3.push_back("G");
Vec3.push_back("T");
vector <vector<string> > allVecs;
allVecs.push_back(Vec1);
allVecs.push_back(Vec2);
allVecs.push_back(Vec3);
string OutputString = EnumAll(allVecs,0,"");
// print the string or process it with other function.
cout << OutputString << endl; // This prints nothing why?
return 0;
}
The expected output is:
TCC
TCG
TCT
TGC
TGG
TGT
TAC
TAG
TAT
CCC
CCG
CCT
CGC
CGG
CGT
CAC
CAG
CAT
ACC
ACG
ACT
AGC
AGG
AGT
AAC
AAG
AAT
You call EnumAll recursively, but you ignore the string that it returns. You have to decide how you are going to aggregate those strings - or what you are going to do with them.
Your function doesn't return anything because your last call doesn't return anything since there's no return and the end of your function.
Edit:
One thing that you can do, is to insert your ResultString to a global vector each time before the return. And at the end, all your results will be available in this vector.
Here is an alternate solution. This does not expect you to pass anything but the initial vectors:
int resultSize( vector< vector<string> > vector ){
int x=1;
for( int i=0;i<vector.size(); i++ )
x *= vector[i].size();
return x;
}
vector<string> enumAll(const vector< vector<string> > allVecs )
{
//__ASSERT( allVecs.size() > 0 );
vector<string> result;
if( allVecs.size() == 1 ){
for( int i=0 ; i< allVecs[0].size(); i++){
result.push_back( allVecs[0][i] );
}
return result;
}
for( int i=0; i<allVecs[0].size(); i++ ){
for( int j=0; j<resultSize( vector< vector<string> >(allVecs.begin()+1, allVecs.end() ) ); j++){
result.push_back( allVecs[0][i] + enumAll(vector< vector<string> >(allVecs.begin()+1, allVecs.end() ))[j] );//enumAll on each tempVector is called multiple times. Can be optimzed.
}
}
}
Advantage of this method:
This is very readable in terms of the recursion. It has easily identifiable recursion base step and also the recursion itself. It works as follows: Each iteration of the recursion enumerates all possible strings from n-1 vectors and the current step simply enumerates them.
Disadvantages of this method:
1. enumAll() function is called multiple times returning the same result.
2. Heavy on stack usage since this is not tail recursion.
We can fix (1.) by doing the following, but unless we eliminate tail recursion, we cannot get rid of (2.).
vector<string> enumAll(const vector< vector<string> > allVecs )
{
//__ASSERT( allVecs.size() > 0 );
vector<string> result;
if( allVecs.size() == 1 ){
for( int i=0 ; i< allVecs[0].size(); i++){
result.push_back( allVecs[0][i] );
}
return result;
}
const vector< vector<string> > tempVector(allVecs.begin()+1, allVecs.end() );
vector<string> tempResult = enumAll( tempVector );// recurse
int size = resultSize( tempVector );
cout << size << " " << tempResult.size() << endl;
for( int i=0; i<allVecs[0].size(); i++ ){
for( int j=0; j<size; j++){
result.push_back( allVecs[0][i] + tempResult[j] );
}
}
}
Your second return should also accumulate the strSoFar in some way. Something like:
for (size_t i=0; i<allVecs[vecIndex].size(); i++)
{
strSoFar = EnumAll(allVecs, vecIndex+1, strSoFar+allVecs[vecIndex][i]);
}
ResultString = strSoFar;
return ResultString;
The code you provided crashes. In the following line, notice that you will be exceeding the limits of vecIndex. There is no check on it in the loop. Also, in the if condition above, you donot reset the vecIndex either. So you will have an access violation.
strSoFar = EnumAll(allVecs, vecIndex+1, strSoFar+allVecs[vecIndex][i]);
To fix it, either rest vecIndex in the if() or use the following for statement:
for (size_t i=0; i<allVecs[vecIndex].size() && vecIndex < allVecs.size(); i++){...}
Edit: However, this does not give the correct output yet.
Your function determines all the correct combinations but they are lost since you do not aggregate them properly.
I see you asked the same question here. I will assume you are now looking for a means to get the output back to the top level so you can handle it from there.
The problem then comes down to how you aggregate the output. You are using a string, but are looking for multiple rows of data. There are infinite answers to this .. here is one using a vector container.
#include <iostream>
#include <vector>
#include <fstream>
#include <sstream>
using namespace std;
void printAll(const vector<string> data);
void EnumAll(const vector<vector<string> > &allVecs, size_t vecIndex, vector<string>&allStr, string strSoFar)
{
if (vecIndex >= allVecs.size())
{
allStr.push_back(strSoFar);
return;
}
for (size_t i=0; i<allVecs[vecIndex].size(); i++)
EnumAll(allVecs, vecIndex+1, allStr, strSoFar+allVecs[vecIndex][i]);
}
int main ( int arg_count, char *arg_vec[] ) {
vector <string> Vec1;
Vec1.push_back("T");
Vec1.push_back("C");
Vec1.push_back("A");
vector <string> Vec2;
Vec2.push_back("C");
Vec2.push_back("G");
Vec2.push_back("A");
vector <string> Vec3;
Vec3.push_back("C");
Vec3.push_back("G");
Vec3.push_back("T");
vector <vector<string> > allVecs;
allVecs.push_back(Vec1);
allVecs.push_back(Vec2);
allVecs.push_back(Vec3);
vector<string> allStr;
EnumAll(allVecs,0,allStr,"");
// print the string or process it with other function.
printAll(allStr);
return 0;
}
void printAll(const vector<string> data)
{
vector<string>::const_iterator c = data.begin();
while(c!=data.end())
{
cout << *c << endl;
++c;
}
}