Consider I've the following code
void foo(int n){
int arr[n];
}
int main(){
foo(5);
}
is there anyway to get the value of n (in this case 5) for the array in the function foo
This is what I've come up with so far
#include <clang/CodeGen/CodeGenAction.h>
#include <clang/Frontend/CompilerInstance.h>
#include <clang/Frontend/CompilerInvocation.h>
#include <clang/Basic/DiagnosticOptions.h>
#include <clang/Frontend/TextDiagnosticPrinter.h>
#include <llvm/ADT/IntrusiveRefCntPtr.h>
#include <llvm/IR/Module.h>
#include <llvm/IR/LLVMContext.h>
#include <llvm/IRReader/IRReader.h>
#include <llvm/Support/SourceMgr.h>
#include <llvm/IR/Instructions.h>
using namespace llvm;
int main(){
llvm::LLVMContext *llvmcx;
static llvm::LLVMContext MyGlobalContext;
llvmcx = &MyGlobalContext;
llvm::SMDiagnostic Err= llvm::SMDiagnostic();
std::unique_ptr<llvm::Module> module=llvm::getLazyIRFileModule("test.ll",Err,*llvmcx,false);
for (auto curFref = module->getFunctionList().begin(), endFref = module->getFunctionList().end();
curFref != endFref; ++curFref) {
for(auto bb=curFref->getBasicBlockList().begin();bb!=curFref->getBasicBlockList().end();bb++){
for(auto ii=bb->getInstList().begin();ii!=bb->getInstList().end();ii++){
if(llvm::dyn_cast<llvm::AllocaInst>(ii)){
AllocaInst *t=dyn_cast<AllocaInst>(ii);
if(t->isArrayAllocation()) {
if (llvm::ConstantInt* CI=dyn_cast<llvm::ConstantInt(t->getArraysize()){
// this if is not satisfied
}
}
}
}
}
}
}
Is there any other way to get the size of a variable sized array?
I have the following code:
Card.h:
#include <string>
class Card
{
public:
enum suits {Spades, Diamonds, Hearts, Clubs};
Card(int _suit, int _value);
std::string SuitToString(int suitidx);
Card();
~Card();
private:
int value;
std::string suit;
};
Card.cpp:
#include <string>
#include <vector>
#include "Card.h"
Card::Card() {
}
Card::Card(int _suit, int _value)
{
this->suit=SuitToString(_suit);
this->value=_value;
}
Card::~Card()
{
}
std::string Card::SuitToString(int suitidx)
{
std::vector<std::string> suitStrings = {"Club", "Diamonds", "Hearts", "Spades"};
return suitStrings[suitidx];
}
Deck.h:
#include "Card.h"
#include <vector>
class Deck: public Card {
public:
Deck();
~Deck();
};
Deck.cpp:
#include "Deck.h"
#include <vector>
Deck::Deck()
{
for (int i=1; i<5; i++) {
for (int j=1; j<14; j++) {
Card c(i,j);
AddCard(c);
}
}
}
Deck::~Deck()
{
}
and main.cpp:
#include "Deck.h"
#include <iostream>
using namespace std;
int main()
{
Deck d;
return 0;
}
But when I run this, I get a seg fault. Can anyone help with this?
#tkausl is right, your Problem is in the SuitToString-Method. You call this with an invalid index.
This is my first "big" C++ project and I am stuck. I am trying to create a simple ASCII roguelike. I have a character class that is inherited by a Player class and a Monster class. The Monster class is inherited by Vampire and Werewolf classes.
In the startGame function of the GameSystem class I submit every element of a Monsters array (that is supposed to be filled with Vampire and Werewolf objects) to the function moveAround. Vampires, Werewolfs, and Monsters all have this function yet only the Monster moveAround function is being accessed. If you notice in the code below I have the virtual keyword provided in the Monster class.
This leads me to think I messed up when I filled the Monster array with the subclasses. I did this in the GameSystem constructor by randomly determining if a particular element of the Monster array was going to be a werewolf or a vampire.
I am using codeblocks and in terms of compiling I have g++ following C++11.
GameSystem.cpp
#include <iostream>
#include <string>
#include "GameSystem.h"
#include "Map.h"
#include "Player.h"
#include "Werewolf.h"
#include "Vampire.h"
#include "conio.h"
#include <cstdio>
#include <stdio.h>
#include <unistd.h>
#include <termios.h>
#include <time.h>
GameSystem::GameSystem(string mapName){
srand (time(NULL));
_map.load(mapName);
_map.obtainSpawningLocations(_player.getToken(),_player);
Werewolf werewolf;
Vampire vampire;
for(int i = 0; i < 5; i++){
_spawnValue = rand() % 2; //We generate either 1 or 2
if(_spawnValue==1){
_theMonsters[i] = werewolf;
cout<<"Werewolf"<<endl;
}
else{
_theMonsters[i] = vampire;
cout<<"Vampire"<<endl;
}
_map.obtainSpawningLocations(_theMonsters[i].getToken(),_theMonsters[i]);
}
}
void GameSystem::startGame(){
bool isOver = false;
while(isOver!=true){
_map.print();
movePlayer();
for(int i = 0; i <5; i++){
_theMonsters[i].moveAround(); //prints out Monster.moveAround()
//I need it to print out Vampire.moveAround() and //Werewolf.moveAround
}
}
}
void GameSystem::movePlayer(){
char input;
input = getch();
string clearScreenString(100,'\n'); //Prints out a newLine char 100 times
cout << clearScreenString;
_map.checkMovement(input, _player);
}
char GameSystem::getch(){
char buf=0;
struct termios old={0};
fflush(stdout);
if(tcgetattr(0, &old)<0)
{perror("tcsetattr()");}
old.c_lflag&=~ICANON;
old.c_lflag&=~ECHO;
old.c_cc[VMIN]=1;
old.c_cc[VTIME]=0;
if(tcsetattr(0, TCSANOW, &old)<0)
{perror("tcsetattr ICANON");}
if(read(0,&buf,1)<0)
{perror("read()");}
old.c_lflag|=ICANON;
old.c_lflag|=ECHO;
if(tcsetattr(0, TCSADRAIN, &old)<0)
{perror ("tcsetattr ~ICANON");}
//printf("%c\n",buf);
return buf;
}
GameSystem.h
#pragma once
#include "Map.h"
#include <string>
#include <list>
using namespace std;
class GameSystem
{
public:
GameSystem(string mapName); //Constructor
void startGame(); //Start the game
char getch();
void movePlayer();
private:
//int _numberOfMonsters = 5; //We'll make this a random number later
Map _map;
Player _player;
Monster _monster;
Monster _theMonsters[5];
int _x;
int _y;
int _spawnValue;
};
Character.cpp
#include <string>
#include "Character.h"
using namespace std;
Character::Character(){
}
char Character::getToken(){
return _token;
}
void Character::setLocation(int x, int y){
_x = x;
_y = y;
}
void Character::getLocation(int &x, int &y){
x = _x;
y = _y;
}
Character.h
#pragma once
#include <string>
class Character{
public:
Character();
char getToken();
void setLocation(int x, int y);
void getLocation(int &x, int &y);
protected:
int _x;
int _y;
char _token = '!';
};
Map.cpp
#include <iostream>
#include <vector>
#include <stdlib.h>
#include <string>
#include <fstream>
#include <cstring>
#include <random>
#include <ctime>
#include <tuple>
#include "Map.h"
#include <time.h>
Map::Map(){
srand (time(NULL));
}
void Map::load(string levelName){
ifstream theStream;
theStream.open(levelName);
if(theStream.fail()){
perror(levelName.c_str());
system("PAUSE");
exit(1);
}
string line;
while(getline(theStream, line)){
_mapData.push_back(line);
}
theStream.close();
}
void Map::obtainSpawningLocations(char characterToken,Character &_character){
/*
Below code provides all the possible spawning locations for the player
and stores them in an array of tuples.
*/
tuple<int,int> myTuple[600]; //Hard coded 600 value is messy. Change later
int numberOfSpawnPoints = 0;
int upperLimitForNumberGenerator = 0;
/*
The for loop below records all of the possible spawning locations and stores them in the tuple array
*/
for(int i = 0; i<_mapData.size();i++){
for(int j = 0; j<_mapData[i].size();j++){
if(_mapData[i][j]=='.'){
get<0>(myTuple[numberOfSpawnPoints]) = j;
get<1>(myTuple[numberOfSpawnPoints]) = i;
numberOfSpawnPoints++;
}
}
}
upperLimitForNumberGenerator = numberOfSpawnPoints;
int characterCoordinates = rand()%upperLimitForNumberGenerator;
int xCoordinate = get<0>(myTuple[characterCoordinates]);
int yCoordinate = get<1>(myTuple[characterCoordinates]);
_mapData[yCoordinate][xCoordinate] = characterToken; //Remember y is first and x is second
_character.setLocation(xCoordinate, yCoordinate);
}
void Map::print(){
for(int i=0;i<_mapData.size(); i++){
printf("%s\n", _mapData[i].c_str());
}
printf("\n");
}
void Map::checkMovement(char input, Player &aPlayer){
int x;
int y;
aPlayer.getLocation(x,y);
char aLocation;
switch(input) {
case 'w':
case 'W': //If 1 up from the player token is a '.' then we move him up
//via a different function
//Otherwise we do nothing.
aLocation = returnLocation(x,y-1);
if(aLocation == '.'){
_mapData[y][x] = '.';
_mapData[y-1][x] = '#';
aPlayer.setLocation(x,y-1);
}
else
cout<<"Can't go here!"<<endl;
break;
case 'a':
case 'A':
aLocation = returnLocation(x-1,y);
if(aLocation == '.'){
_mapData[y][x] = '.';
_mapData[y][x-1] = '#';
aPlayer.setLocation(x-1,y);
}
else
cout<<"Can't go here!"<<endl;
break;
case 's':
case 'S':
aLocation = returnLocation(x,y+1);
if(aLocation == '.'){
_mapData[y][x] = '.';
_mapData[y+1][x] = '#';
aPlayer.setLocation(x,y+1);
}
else
cout<<"Can't go here!"<<endl;
break;
case 'd':
case 'D':
aLocation = returnLocation(x+1,y);
if(aLocation == '.'){
_mapData[y][x] = '.';
_mapData[y][x+1] = '#';
aPlayer.setLocation(x+1,y);
}
else
cout<<"Can't go here!"<<endl;
break;
default:
cout<<"Invalid input";
system("PAUSE");
break;
}
}
char Map::returnLocation(int x, int y){
cout<<x<<endl;
cout<<y<<endl;
char aSpot = _mapData[y][x];
return aSpot;
}
Map.h
#pragma once
#include <vector>
#include <fstream>
#include <string>
#include <tuple>
#include <ctime>
#include <random>
#include "Player.h"
#include "Monster.h"
using namespace std;
class Map
{
public:
Map(); //Constructor
void load(string levelName);
void obtainSpawningLocations(char characterToken, Character &aCharacter);
void checkMovementMonsters(char input, Monster &aMonster);
//void obtainSpawningLocationsForMonsters(char characterToken, Monster aMonster);
void print();
void checkMovement(char input, Player &aPlayer);
void movement(char characterToken);
char returnLocation(int x,int y);
// int numberOfSpawnPoints;
private:
vector <string> _mapData;
Player _player;
Monster _monster;
};
Monster.cpp
#include <iostream>
#include <string>
#include "Monster.h"
using namespace std;
Monster::Monster(){
}
void Monster::moveAround(){
cout<<"Monster Mash"<<endl;
}
Monster.h
#pragma once
#include <string>
#include "Character.h"
class Monster: public Character{
public:
Monster();
virtual void moveAround();
protected:
char _token = 'M';
int _x;
int _y;
};
Werewolf.cpp
#include <iostream>
#include <string>
#include "Werewolf.h"
using namespace std;
Werewolf::Werewolf(){
}
void Werewolf::moveAround(){
cout<<"Werewolf moving around"<<endl;
}
Werewolf.h
#pragma once
#include <string>
#include "Character.h" //For inheritance/polymorphism
#include "Monster.h"
class Werewolf: public Monster{
public:
Werewolf();
void moveAround();
private:
char _token = 'W';
};
Vampire.cpp
#include <iostream>
#include <string>
#include "Vampire.h"
using namespace std;
Vampire::Vampire(){
}
void Vampire::moveAround(){
cout<<"Vampire moving around"<<endl;
}
Vampire.h
#pragma once
#include <string>
#include "Character.h" //For inheritance/polymorphism
#include "Monster.h"
class Vampire: public Monster{
public:
Vampire();
virtual void moveAround();
private:
char _token = 'V';
};
Player.cpp
Player::Player(){
}
Player.h
#pragma once
#include <string>
#include "Character.h"
using namespace std;
class Player : public Character {
public:
Player();
protected:
int _x;
int _y;
char _token = '#';
};
Main
#include <iostream>
#include "GameSystem.h"
using namespace std;
int main()
{
GameSystem gameSystem("LevelOne.txt");
gameSystem.startGame();
return 0;
}
The level text file:
############################################
#..........................................#
#..........................................#
#...........................^..............#
#..........................................#
#......................#...................#
#......................#...................#
#......................#...................#
#............^.........#...................#
#......######..........#..&................#
#......\...............#...................#
#......................#...................#
#..........................................#
#..........................................#
############################################
There is no virtual dispatch happening on _theMonsters[i].moveAround(). You need to have an array of pointers to objects of type monster. In fact, there are quite some problems in the way you try to set up the class hierarchy, like, having identically named member variables in derived classes.
There are a couple of issues here.
Monster::_token, Werewolf::_token, and Vampire::_token are all different variables. A Werewolf object has both Monster::_token and Werewolf::_token.
Monster _theMonsters[5] is an array of 5 Monster objects. It will never be a Vampire or a Werewolf, always a Monster. There is no virtual dispatch to be done since the objects will always be the same type: Monster.
Virtual dispatch only applies to pointers and references. To make this work, you'll need to use an array of pointers to Monsters: Monster* _theMonsters[5]. Then you can fill it like _theMonsters[i] = new Vampire(). If you do this, you'll need to remember to delete the objects when you're done with them, or you could use a smart pointer like std::unique_ptr or std::shared_ptr instead of raw Monster*s.
I am getting a segmentation fault error after inserting an input file in this program I can't find where is the problem, could anyone help me with this?(it's the solution for the USACO training milk2 question).
#include <algorithm>
#include <bitset>
#include <limits>
#include <climits>
#include <cmath>
#include <cstring>
#include <ctime>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
int main ()
{
std::ifstream in ("milk2.in");
std::ofstream out ("milk2.out");
std::vector< pair <int,int> > v;
int n,i,maxn,maxs,t,ts;
in >> n;
for (i = 0; i < n; i++)
{
in >> v[i].first >> v[i].second;
}
for (i = 0; i < n; i++)
{
if (v[i].second<(v[i+1].first)
{
t=v[i+1].first-v[i].second;
if (t>maxn){
maxn=t;
}
}
else
{
ts=v[i+1].second-v[i].first;
if (ts>maxs)
{
maxs=ts;
}
}
}
out << maxs <<" "<< maxn;
return 0;
}
When you create the vector v, it's empty. So any index, even zero, will be illegal.
You need to first create the entries in the vector, e.g. by doing push_back.
I am trying to learn how Boost UUID works. I have made the following code
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <iostream>
using namespace std;
using namespace boost;
using namespace uuids;
int main() {
for (int i = 0; i < 40; ++i){
uuid uuid = random_generator()();
cout <<i+1<<" "<<"\t"<<uuid << endl;
}
system("pause");
return 0;
}
In this code i generate 40 lines with UUID codes. I want to place these lines in a function and call them by my main class int main()
Any ideas how to do this?
Generate them into a standard library container, such as e.g. std::vector<uuid>:
std::vector<uuid> foo() {
std::vector<uuid> r;
std::generate_n(back_inserter(r), 40, random_generator());
return r;
}
Live On Coliru
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <iostream>
using namespace std;
using namespace boost;
using namespace uuids;
std::vector<uuid> foo() {
std::vector<uuid> r;
std::generate_n(back_inserter(r), 40, random_generator());
return r;
}
int main() {
for(auto& uuid : foo())
cout << uuid << endl;
}