Apparently since its a segfault the C++ compiler won't output anything? I'm having some trouble with some C++ code I wrote. I'm a novice and I've been looking for this segfault for some time now... I can't figure it out.
My best guess is it is somewhere in the Deck() constructor, can anyone give me a hand?
Any help would be appreciated!
Thanks!
Follow up: In the future, does anyone have any good methods of debugging segfaults?
Deck.cpp
#include "Deck.h"
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using std::ostream;
using std::vector;
const string Deck::RANKS[13] = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
const string Deck::SUITS[4] = {"H","D","C","S"};
string cards[52];
int card = 0;
Deck::Deck() : size(0)
{
for (int i = 0; i < 13; i++)
{
for (int j = 0; j < 4; j++)
{
cards[size] = RANKS[i] + SUITS[j];
size++;
}
}
shuffle();
}
Deck::~Deck() {}
void Deck::shuffle()
{
size = MAX_SIZE;
std::random_shuffle(&cards[0], &cards[MAX_SIZE-1]);
}
string Deck::getCard()
{
card++;
return cards[card-1];
}
Deck.h
#ifndef DECK_H
#define DECK_H
#include <ostream>
#include <string>
#include <vector>
using std::ostream;
using std::string;
using std::vector;
class Deck
{
private:
static const int MAX_SIZE = 52;
static const string RANKS[13];
static const string SUITS[4];
static const string DECK[52];
int size;
public:
Deck();
~Deck();
void shuffle();
string getCard();
int getDeckSize() const {return size;}
friend ostream& operator<<(ostream&, const Deck&);
};
#endif
Main.cpp
#include <iostream>
#include "Deck.h"
using namespace std;
int main()
{
int pairs = 0;
for(int x = 0; x < 100; x++)
{
cout << "yep";
Deck deck;
cout << "awooga";
deck.shuffle();
cout << "hai";
string cards[2];
cards[0] = deck.getCard();
cards[1] = deck.getCard();
for(int y = 0; y < 5; y++)
{
string tempCard = deck.getCard();
if(cards[0].compare(tempCard) == 0 || cards[1].compare(tempCard) == 0)
{
pairs++;
}
}
}
cout << pairs;
return 0;
}
Your problem is that getCard has side effects, increasing the value of card every time you call it. As soon as you call it more than 52 times, your program may crash. Note that card is a global variable and doesn't reset to zero whenever you create a new deck.
I also noticed that your call to random_shuffle has an off-by-one error. The end iterator needs to be one beyond the actual end of your container, not pointing at the end (so it's a half-open range).
Finally for debugging segmentation faults in general, enable core dumps on your system and use gdb to attach the core to your binary. That will sometimes give you a good clue where to start.
Related
Forgive my ignorance. I'm still at the beginning of C++, and am having a hard time grasping the language, since it is my first.
How would I call the strings or int in a function into another function so I would be able to separate the different processes required for the program?
I'm really sorry if it's messy, from my understanding the code should work, but it is displaying nothing on the main.cpp file.
This is a full house probability checker. I'm supposed to run a bunch of rounds and deal out five cards and check if they are a full house. Please tell me what I can improve on, and what I lack in my understanding.
class.cpp
#include <iostream>
#include "Class.h"
#include <ctime>
#include <cstdlib>
#include <string>
using namespace std;
void shufflewell()
{
srand(time(0));
int deck[52];
int i;
// deck shuffling
for(i=0; i<52; i++)
{
int j = rand() % 52;
int temp = deck[i];
deck[i] = deck[j];
deck[j] = temp;
}
}
void DisplayCard ()
{
void shufflewell();
int i;
int deck[52];
string suitnames[4]={"spades", "diamonds", "clubs", "hearts"};
string ranknames[13]={"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"};
int suitnumber = deck[i] / 13; // 0 - 3
int rank = deck[i] % 13;
cout << ranknames[rank] << " of " << suitnames[suitnumber] << endl;
// Get the rank of the first 5 cards
int R[5]; // = {4, 7, 6, 3, 5}; // rank of the first 5 cards
int S[5];
for(i=0; i<5; i++)
{
R[i] = deck[i]%13;
S[i] = deck[i]/13;
}
cout << ranknames[R[i]] << " of " << suitnames[S[i]];
return DisplayCard();
}
// Deals five random cards to player
void dealHand()
{
for(int i = 0; i < 5; i++)
{
DisplayCard();
cout << ranknames[R[i]] << " of " << suitnames[S[i]];
}
}
main.cpp
#include <iostream>
#include <cstdlib>
#include "Class.h"
using namespace std;
int main()
{
cout << "Full house probabilty checker";
void DisplayCard();
return 0;
}
Class.h
#ifndef Class.h
#define Class.h
#include <iostream>
#include <string>
using namespace std;
class cards
{
public:
int i;
int deck[52];
std::string suitnames;
std::string ranknames;
void shufflewell();
void DisplayCard();
void dealHand();
};
#endif // Class
Since C++ is your first language I would suggest reading up on on proper syntax form. Things like calling functions, creating classes and declaring member functions to name a few.
In C++ class member functions are conventionally implemented using a declaration:
// class.h
class cards
{
public:
/* ... */
void DisplayCard();
};
Definition:
// class.cpp
#include "class.h"
void cards::DisplayCard()
{
/* ... */
}
And get called like this:
class_Instance.DisplayCard();
In addition, you are calling DisplayCard from within itself:
void DisplayCard()
{
/* ... */
return DisplayCard();
}
Which causes a stackoverflow - function being executed an exceeding amount of times.
Here are a few resources on how classes and objects are created and used in C++:
https://www.programiz.com/cpp-programming/object-class
https://www.w3schools.com/cpp/cpp_classes.asp
https://cplusplus.com/doc/tutorial/classes/
I'm working on an assignment to create a class called StringBuilder that is used for fast string concatenation. I'm supposed to store strings in a dynamic array and have methods such as Append(string) which adds a new string to the dynamic array. The method I'm currently struggling with is GetString() that creates a single string on the heap that is the length of all the strings in the dynamic array that have been added thus far.
the code I have so far is:
okay my main problem is my GetString() function prints out hello over and over again until I force quit the program in Xcode. I don't understand what inside that method is making that happen.
My header file:
#pragma once
#include <string>
using namespace std;
class StringBuilder
{
public:
StringBuilder();
//~StringBuilder();
void GetString();
void AppendAll(string*, int);
void Length();
void Clear();
void Append(string userString);
void DoubleArray(string*& allWords, int newCapacity);
private:
string* p_array;
int capacity = 5;
};
my .cpp file :
#include "StringBuilder.hpp"
#include <iostream>
#include <string>
using namespace std;
----------
void StringBuilder::Append(string userString)
{
int nextWordPosition = 0;
for(int i=0; i < capacity ; i++)
{
p_array[i] = userString;
cout << p_array[i] << endl;
nextWordPosition +=1;
if(capacity == nextWordPosition)
{
capacity *=2;
DoubleArray(p_array, capacity * 2);
}
}
nextWordPosition++;
}
void StringBuilder::DoubleArray(string*& allWords, int newCapacity)
{
string* p_temp = new string[newCapacity];
for(int i =0; i < newCapacity / 2; i++)
{
p_temp[i] = allWords[i];
}
delete[] allWords;
allWords = p_temp;
}
void StringBuilder:: GetString()
{
for(int i=0; i < capacity ; i++)
{
cout << p_array[i]<< endl;
}
}
my main.cpp file :
#include <iostream>
#include <string>
#include "StringBuilder.hpp"
using namespace std;
int main()
{
string testString = "hello";
string test = "world!";
StringBuilder Builder1;
Builder1.Append(testString);
Builder1.Append(test);
Builder1.GetString();
return 0;
}
I have a class "beaker" that represents a beaker with n-dices that have n-faces. It has a method "roll" which returns a vector with n-elements where each element represents a dice. Then I have another class "board" that for now, it only prints the values generated by beaker.roll using cout;
So I call the beaker.roll function to pass the result to print them, but it does nothing. I have no compile errors/IntelliSense warnings. What am I doing wrong?
#include <iostream>
#include <random>
#include <chrono>
#include <thread>
#include <vector>
using std::cout;
using std::vector;
class beaker {
public:
int diceCount, diceFaces;
beaker() {
diceCount = 2;
diceFaces = 6;
};
beaker(int count, int faces) {
diceCount = count;
diceFaces = faces;
};
//Dice values
vector<uint8_t> dice;
//METHODS
//RETURN DICE i VALUE
int diceValue(int d) {
return dice.at(d-1);
}
//ROLL DICE + RETURN RESULT
vector<uint8_t> roll() {
std::mt19937 mt(std::chrono::high_resolution_clock::now().time_since_epoch().count());
std::uniform_int_distribution<int> dist(1, diceFaces);
for (int i=0; i<diceCount; i++) {
dice.push_back(dist(mt));
}
return dice;
}
//RETURN LAST DICE NUMBERS
vector<uint8_t> result() {
return dice;
}
};
class board {
public:
void Print(vector<uint8_t> dice) {
for (int i=0; i<dice.size(); i++) {
cout << dice.at(i);
}
}
};
int main() {
beaker beaker;
board board;
board.Print(beaker.roll());
}
The problem is that the values in dice are of type uint8_t, which the cout::<< operator is interpreting as unsigned char, so it is printing out the values as ASCII characters. However, the values are between 1 and 6, and ASCII characters less than 32 are mostly non-printing characters, so they aren't visible in the output.
To convince the cout::<< operator to print the values as integers instead, update the code to this:
void Print(vector<uint8_t> dice) {
for (int i=0; i<dice.size(); i++) {
cout << static_cast<int>(dice.at(i));
}
cout << std::endl; // just to make sure the buffer gets flushed ASAP
}
Card.h
#pragma once
#include <string>
#include "Rank.h"
#include "Suit.h"
using namespace std;
/**
*
*/
class MEMORYWARS_API Card
{
public:
Card(Rank, Suit);
string toString() const;
~Card();
private:
Rank rank;
Suit suit;
};
Card.cpp
#include "MemoryWars.h"
#include "Card.h"
Card::Card(Rank rank, Suit suit)
{
this->rank = rank;
this->suit = suit;
}
string Card::toString() const
{
string s = "Hellow there";
return s;
}
Card::~Card()
{
}
Error
error C3867: 'Card::toString': non-standard syntax; use '&' to create a pointer to member
Deck.h
#pragma once
#include "Card.h"
#include "vector"
class MEMORYWARS_API Deck
{
public:
Deck();
~Deck();
private:
std::vector<Card> deck;
};
Deck.cpp
#include "MemoryWars.h"
#include "Deck.h"
#include <EngineGlobals.h>
#include <Runtime/Engine/Classes/Engine/Engine.h>
Deck::Deck()
: deck(52)
{
int cc = 0;
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 13; j++)
{
Rank rank = static_cast<Rank>(j);
Suit suit = static_cast<Suit>(i);
deck[cc] = Card(rank, suit);
cc++;
}
}
string st = deck[2].toString;
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("Some variable values: x: %s"), st));
}
Deck::~Deck()
{
}
I'm new to C++ with Java experience mainly, I have been struggling with this error.
I'm trying to test the Card::toString method but everytime I call it from deck.cpp I get an error.
This line here is not correct:
string st = deck[2].toString;
The proper way to call a function in C++ (actually Java too I thought) is this:
string st = deck[2].toString();
I'm working with c++ STL vectors, and have a vector of structures called projectileList. I'm trying to iterate through the vector, getting and setting values in the struts as I iterate, but my code refuses to compile, with the error 'Incomplete type is not allowed.'
Can anyone please point out what I'm doing wrong:
Code:
ProjectHandeler.h:
#include "stdafx.h"
#include "DataTypes.h"
#include <vector>
class ProjectileHandeler {
private:
int activeObjects;
std::vector<projectile> projectileList;
void projectileUpdater();
public:
ProjectileHandeler(projectile* input[], int projectileCount);
~ProjectileHandeler();
};
#endif
projectileHandeler.cpp
#include "stdafx.h"
#include "DataTypes.h"
#include "ProjectHandeler.h"
#include <vector>
ProjectileHandeler::ProjectileHandeler(projectile* input[], int projectileCount)
{
for (int i = 0; i < projectileCount; i++)
{
projectileList.push_back(*input[i]);
activeObjects += 1;
}
//NO extra slots. Not that expensive.
projectileList.resize(projectileList.size());
}
void ProjectileHandeler::projectileUpdater()
{
while (true)
{
for (unsigned int i = 0; i < projectileList.size(); i++)
{
if (projectileList[i].isEditing == true)
break;
}
}
}
This compiles fine (tested it here: http://codepad.org/cWn6MPJq):
#include <vector>
struct projectile {
bool isEditing;
};
class ProjectileHandeler {
private:
std::vector<projectile> projectileList;
void projectileUpdater()
{
//This bit loops to infinity and beyond! ...or at least untill the handeler is destroyed.
while (true)
{
for (unsigned int i = 0; i < projectileList.size(); i++)
{
if (projectileList[i].isEditing == true) //Throws Incomplete type error
break;
}
}
}
};
int main()
{
}
Notice the removal of *, correct type of loop variable and removal of extra class specifier.