Memory leak involving an unloaded shared object? - c++11

I am trying to understand this programming problem whereby I am supposed to guess the data structures. I am having a slight issue with my program.
PROBLEM: I have no clue as to why my program always gets killed with signal 11 (segmentation fault) but it works and compiles fine.
About the program: n would be number of integer sets ; it takes in an integer p (command) and integer data and pushes/pops into the following data structures. I've use a bool as flag to check the statuses. Am I right to believe the structures would be destroyed after the while loop as it goes out of scope?
int main(){
int n;
while (cin >> n && n != 0){
stack<int> mystack;
queue<int> myqueue;
priority_queue<int> maxq;
bool isstack = true;
bool isqueue = true;
bool ispq = true;
for (int i = 0; i < n; i++){
int p, data;
cin >> p >> data;
if (p == 1){
if (isqueue) myqueue.push(data);
if (isstack) mystack.push(data);
if (ispq) maxq.push(data);
} else if (p == 2){
if ((mystack.empty() || mystack.top() != data) && isstack) isstack = false;
else mystack.pop();
if ((myqueue.empty() || myqueue.front() != data) && isqueue) isqueue = false;
else myqueue.pop();
if ((maxq.empty() || maxq.top() != data) && ispq) ispq = false;
else maxq.pop();
}
}
if (isstack && !(isqueue || ispq)) cout << "stack" << endl;
else if (isqueue && !(isstack || ispq)) cout << "queue" << endl;
else if (isstack && (ispq || isqueue) || (isqueue && ispq)) cout << "not sure" << endl;
else if (ispq && !(isstack || isqueue)) cout << "priority queue" << endl;
else cout << "impossible" << endl;
}
return 0;
}

Yes, the data structures you’ve used are local scope to while, so they get destructed at the end of while loop.
Unless you provide for what input you’re seeing segmentation fault, it’s hard to say. Or run it in debug mode, your program should break at line where seg fault occurs.

I tried to run this code.
This code threw an exception when you pop after 'isstack' was changed to false.
The exception was 'Expression: deque empty before pop'.
After the variable changed false, always condition statements are return false.
So you tried to pop at empty stack.
That is a just logical bug.

Related

Efficient checking for Subset

Given two bitset objects 'B1' and 'B2' of length 'n' respectively. Whats the efficient way to say whether all the bits that are set in 'B2' are also in 'B1'?
Example:
B1 = 110111
B2_bad = 011001
B2_good = 100001
So, 'B1' and 'B2_good' is good but not 'B1' and 'B2_bad'?
Well, I guess these two following methods might help. You might need to benchmark them as which is faster.
std::bitset<6> B1 (std::string("110111"));
std::bitset<6> B2_bad (std::string("011001"));
std::bitset<6> B2_good (std::string("100001"));
//////////////One way/////////////////////////
if ( (~B1 &= (B2_bad)).any()) std::cout << "No" << std::endl;
else std::cout << "Yes" << std::endl;
if ( (~B1 &= (B2_good)).any()) std::cout << "No" << std::endl;
else std::cout << "Yes" << std::endl;
///////////////Second way//////////////////
int i =0;
for (i = 0; i < B1.size(); ++i) if (B2_bad[i] == 1 && B1[i] == 0) break;
if (i == B1.size()) std::cout << "Yes" << std::endl;
else std::cout << "No" << std::endl;
for (i = 0; i < B1.size(); ++i) if (B2_good[i] == 1 && B1[i] == 0) break;
if (i == B1.size()) std::cout << "Yes" << std::endl;
else std::cout << "No" << std::endl;`
Probably, someone more proficient than me can comment on their performance. But my best guess is first method leverages the library functions which should give the best performance , however if most of your queries would have 'Result NO' and B1-B2 will not agree on one of the earlier bits then second method might have better runtime. As, library functions involved have a worst runtime complexity of O(n).

Functions not executing properly

So I'm trying to write a program that solves the "Dungeon Crawl" problem here: http://www.cplusplus.com/forum/articles/12974/. If you are too lazy to read the link (which is entirely understandable), the basic premise of the game is that a player moves on a 10x10 grid and tries to reach treasure while avoiding traps and moving enemies. Because everything is revealed to the player, it's not much of a real game, but I thought it'd be good coding practice. Sadly, I'm rusty on user input and never properly learned how to put an entire program together, which means I'm having serious problems with functions executing properly.
The main function is this:
int main()
{
int turn=0,enemyCount=0;
bool end=false;
srand (time(NULL));
node* world;
world = new node[100];
generateWorld(world);
drawWorld(world);
do {
playerMove(world);
enemiesMoves(world,enemyCount);
drawWorld(world);
end = endCheck(world);
turn++;
} while (end == false);
return 0;
}
I think this is fine as is, because it follows the simple process of gathering moves, updating the world, and then checking to see if an end condition has been reached. The problem is that numerous functions are not working as I would expect them to, and I can't figure out why they are not. This includes user input validation, updating the movement of the enemies, drawing the world, and checking if the game ended. I'll go in order.
This is the playerMove() function:
void playerMove(node* array){
int i,playerLocation,oldLocation;
bool valid=false;
char move;
for (i=0;i<100;i++){
if (array[i].player == true){
playerLocation = i;
oldLocation = playerLocation;
}
}
while(!valid){
if (cin >> move){
if (move=='w' || move=='s' || move=='a' || move=='d')
valid = true;
}
if (move=='w'){
playerLocation = oldLocation-10;
if (playerLocation < 0){
cout << "You can't swim." << endl;
valid = false;
}
}
else if (move=='s'){
playerLocation = oldLocation+10;
if (playerLocation > 99){
cout << "You can't swim." << endl;
valid = false;
}
}
else if (move=='a'){
playerLocation = oldLocation-1;
if (playerLocation % 10 == 9){
cout << "You can't swim." << endl;
valid = false;
}
}
else if (move=='d'){
playerLocation = oldLocation+1;
if (playerLocation % 10 == 0){
cout << "You can't swim." << endl;
valid = false;
}
}
}
array[oldLocation].player = false;
array[playerLocation].player = true;
}
It's supposed to gather player input, do nothing if the player enters a key that isn't WASD (they can only move in the four cardinal directions), reject an input if the player tries to move off the edge of the world, and update the player position. It does successfully do the latter, but it will not catch an invalid input, and if a move fails, it refuses to display the message it is supposed to.
This is the enemiesMoves function:
void enemiesMoves(node* array,int enemyCount){
int i,j=0,n,enemyLocations[enemyCount],oldLocations[enemyCount];
bool valid = false;
for (i=0;j<enemyCount;i++){
if (array[i].enemy==true){
enemyLocations[j] = i;
cout << enemyLocations[j] << endl;
j++;
}
}
for (j=0;j<enemyCount;j++){
oldLocations[j] = enemyLocations[j];
}
for (j=0;j<enemyCount;j++){
while (!valid){
n = rand() % 4 + 1;
if (n = 1){
enemyLocations[j] = oldLocations[j]-10;
if (enemyLocations[j] < 0)
valid = false;
}
else if (n = 2){
enemyLocations[j] = oldLocations[j]+10;
if (enemyLocations[j] > 100)
valid = false;
}
else if (n = 3){
enemyLocations[j] = oldLocations[j]-1;
if (enemyLocations[j] % 10 == 9)
valid = false;
}
else if (n = 1){
enemyLocations[j] = oldLocations[j]+1;
if (enemyLocations[j] % 10 == 0)
valid = false;
}
}
array[enemyLocations[j]].enemy = true;
array[oldLocations[j]].enemy = false;
}
}
It is supposed to move the enemies in a random direction, but reject the movement if the enemy moves off the world. Although I thought I properly copied over the playerMove() code to this, it refuses to update the position of the enemies; they stay in the same place turn after turn.
This is the drawWorld() function:
void drawWorld(node* array){
int i;
for (i=0;i<100;i++){
if (array[i].player==true)
cout << "P";
else if (array[i].trap==true)
cout << "T";
else if (array[i].enemy==true)
cout << "E";
else if (array[i].treasure==true)
cout << "X";
else if (array[i].player==true && array [i].treasure==true)
cout << "W";
else if ((array[i].player==true && array[i].trap==true) || (array[i].player==true && array[i].enemy==true))
cout << "L";
else {
cout << "O";
}
if ((i+1 % 10) == 0){
cout << endl;
}
}
cout << endl << endl;
}
It draws the world fine, except that it won't wrap the text every ten characters as it is plainly told to do. I can't fathom what I'm missing here.
Finally, this is the endCheck() function:
bool endCheck(node* array){
int i;
for (i=0;i<100;i++){
if (array[i].player==true && array[i].treasure==true){
cout << "You found the treasure and now enjoy a life of unmitigated opulence." << endl;
return true;
}
else if (array[i].player==true && array[i].trap==true){
cout << "You fell into a conspicuous trap and became tiger food." << endl;
return true;
}
else if (array[i].player==true && array[i].enemy==true){
cout << "You were captured alive by angry natives and enjoyed as part of their New Year's feast." << endl;
return true;
}
else
return false;
}
}
This is simply not executing at all. I can move the player onto a trap and nothing happens.
These problems are incredibly frustrating because I am simply unable to discern what is wrong with the code. I know the post is long, but if anyone could point out what's wrong it'd be greatly appreciated. Also it should be noted that I searched for answers before posting this, but because I think the problems are intrinsic to my code I was unable to find any usable answers.
You are returning at the end of first iteration. So it will check only first field and then return false (if there was no player and treasure/trap/enemy in first field).
Change your function to look like this:
bool endCheck(node* array){
int i;
for (i=0;i<100;i++){
if (array[i].player==true && array[i].treasure==true){
cout << "You found the treasure and now enjoy a life of unmitigated opulence." << endl;
return true;
}
else if (array[i].player==true && array[i].trap==true){
cout << "You fell into a conspicuous trap and became tiger food." << endl;
return true;
}
else if (array[i].player==true && array[i].enemy==true){
cout << "You were captured alive by angry natives and enjoyed as part of their New Year's feast." << endl;
return true;
}
}
return false;
}
You have to check all possible fields before returning false that indicates no collision.
In enemiesMoves(), you are checking if(n = 1), I'm sure you meant if(n == 1).
Do this:
....
n = rand() % 4 + 1;
if (n == 1){
.....
Also, n == 1 case is checked twice! Once in if and then in the last else if.
For the rand() function to actually generate random numbers on each run, initialize a random seed first using srand(), as follows:
/* initialize random seed: */
srand (time(NULL));
n = rand() % 4 + 1;

Simple coding to Stack

int main()
{
string sentence;
int length;
cout << "Enter the sentence now." << endl;
getline(cin, sentence);
for(int i = 0; i < sentence[i]; i++)
{
if(sentence[i]==';')
cout<<" ";
else if(sentence[i] != ' ')
{
cout << sentence[i];
}
else if(sentence[i] == ' ')
{
cout << endl;
}
}
}
I need help in this code to change into stack coding method. At least you can show me some clue how to change this code into simple stack code.
cin>>a>>b>>c>>d>>e>>f>>g;
myStack.push(g);
myStack.push(f);
myStack.push(e);
myStack.push(d);
myStack.push(c);
myStack.push(b);
myStack.push(a);
while(!myStack.empty()){
cout<<myStack.top()<<endl;
myStack.pop();
}
return 0;
}
This is an example, but its not flexible. User only can enter 7 words or maybe we can do it in array?

Sentinel not working?

I'm not sure why this isn't working, but this is my error message:
Error] no match for 'operator!=' (operand types are 'std::string {aka std::basic_string}' and 'const int')
EDIT: The above issue has been resolved. But, the current issues are redundant ***, and the lack of vowel removal in a sentence rather than just the first word of a sentence.
#include <iostream>
#include <string>
using namespace std;
void removeVowel(string&); // Removes vowels from input string.
string withVowel; // Will be used to read user input.
int main ()
{
const string SENTINEL = "0"; // Sentinel value.
// Request input string unless SENTINEL is entered.
cout << "Enter a word or series of words. " << '\n';
cout << "Or, enter " << SENTINEL << " to quit. " << endl;
cin >> withVowel;
// In case of SENTINEL:
while (withVowel == SENTINEL)
{
cout << "***" << endl;
}
// Run loop.
removeVowel(withVowel);
// Display the string without vowels.
cout << "The word(s) entered reflecting only consonants: " << withVowel << endl;
return 0;
}
void removeVowel(string& withVowel)
{
int i = 0;
int length = int(withVowel.length());
while (i < length)
{
if (withVowel.at(i) == 'a' ||
withVowel.at(i) == 'A' ||
withVowel.at(i) == 'e' ||
withVowel.at(i) == 'E' ||
withVowel.at(i) == 'i' ||
withVowel.at(i) == 'I' ||
withVowel.at(i) == 'o' ||
withVowel.at(i) == 'O' ||
withVowel.at(i) == 'u' ||
withVowel.at(i) == 'U')
{
withVowel.erase(i, 1);
length = int(withVowel.length());
}
else i++;
}
// Display the string without vowels.
cout << removeVowel << endl;
}
Based on your other question, and the error message, I assume withVowel is a std::string. The error message is pretty much telling you what the problem is: you can't compare a std::string with an int.
Since you only need SENTINEL for printing and comparison, just declare it as a std::string as well:
const std::string SENTINEL = "0";
You can't compare const int with strings.
Use ctrl+z and enter to stop the input.
string word;
cout << "ctrl+z and Enter to exit\n";
while (cin >> word){
cout << word << ' ';
// other processing
}
And for your case:
cout << "Enter a word or series of words.\n";
cout << "Ctrl+z and Enter to exit\n";
while (cin >> withVowel){
removeVowel(withVowel);
cout << "The word(s) entered reflecting only consonants :" << withVowel << endl;
}

Remove Vowels from more than first word

Program compiles, runs, and works.
Big issue:
It only works for the first word of a sentence.
EXAMPLE:
"Welcome to the jungle" results in "wlcm" rather than "wlcm t th jngl".
Small Issue:
There's a "1" appearing between input and output when it runs. How can I get rid of that? I think it's from this, but I'm not positive:
{
withVowel.erase(i, 1);
length = int(withVowel.length());
}
WHOLE CODE:
#include <iostream>
#include <string>
using namespace std;
void removeVowel(string&); // Removes vowels from input string.
string withVowel; // Will be used to read user input.
int main ()
{
const string SENTINEL = "0"; // Sentinel value.
// Request input string unless SENTINEL is entered.
cout << "Enter a word or series of words." << '\n';
cout << "Or, enter " << SENTINEL << " to quit." << '\n' << endl;
cin >> withVowel;
// In case of SENTINEL:
while (withVowel == SENTINEL)
{
cout << '\n' << "***" << endl;
return 0;
}
// Run loop.
removeVowel(withVowel);
// Display the string without vowels.
cout << "The word(s) entered reflecting only consonants: " << withVowel << endl;
return 0;
}
void removeVowel(string& withVowel)
{
int i = 0;
int length = int(withVowel.length());
while (i < length)
{
if (withVowel.at(i) == 'a' ||
withVowel.at(i) == 'A' ||
withVowel.at(i) == 'e' ||
withVowel.at(i) == 'E' ||
withVowel.at(i) == 'i' ||
withVowel.at(i) == 'I' ||
withVowel.at(i) == 'o' ||
withVowel.at(i) == 'O' ||
withVowel.at(i) == 'u' ||
withVowel.at(i) == 'U')
{
withVowel.erase(i, 1);
length = int(withVowel.length());
}
else i++;
}
// Display the string without vowels.
cout << removeVowel << endl;
}
Use getline(cin, withVowel); instead of cin >> withVowel;
Also replace while with if in main().
And don't forget to upvote and accept answers=)
The problem with only getting the first word is being you're using cin >> withVowel;, which will stop reading input as soon as it encounters white space. Try using std::getine(cin, withVowel); instead.
If at all possible, I would avoid manipulating the string in place, and just copy things to the output if they're not vowels.
std::remove_copy_if(withVowel.begin(), withVowel.end(),
[](char c) { return c == 'a' || c == 'A' ||
c == 'e' || c == 'E' ||
c == 'i' ...;});

Resources