So I decided to make a console class as an alternative to std::cout << stream << std::endl routine.
Here's my code:
class Console {
public:
Console() {
this->console = GetStdHandle(STD_OUTPUT_HANDLE);
this->current_color = 7;
}
void color(int k) {
this->current_color = k;
SetConsoleTextAttribute(this->console, this->current_color);
}
void remove() {
FreeConsole();
}
void print(std::string s) {
std::cout << s;
}
void log(std::string s) {
this->color(7);
std::cout << s << std::endl;
this->color(this->current_color);
}
void error(std::string s) {
this->color(12);
std::cout << s << std::endl;
this->color(this->current_color);
}
private:
HANDLE console;
int current_color;
};
Initializing console as Console console;, I use console.log("String " + n), where n is an unsigned short, for example. The code compiles fine, however this thing shows up:
What is it and how do I fix it?
Your program contains undefined behavior.
console.log("String " + n) (where n is an integral type) is interpreted as follows:
const char* tmp_ptr1 = "String ";
const char* tmp_ptr2 = tmp_ptr1 + n;
console.log(std::string(tmp_ptr2));
If n > 7 or n < 0 the code above performs out-of-bounds access. In your case this access happens to pick up some other (sub)string from the string literals linked into your program's data section and you see it on your screen. In theory anything else could happen.
Related
I am implementing my own smart_pointer, which counts the references to the thing it points to. Here is my implementation so far:
#pragma once
#include <iostream>
template <typename T>
class smart_pointer{
T* pointer;
int* cnt;
public:
smart_pointer<T>(T *el): pointer(el) { int i = 1; cnt = &i; }; //
smart_pointer<T>(const smart_pointer<T>& other): pointer(other.pointer) {
// std::cout << ", *(other.cnt): " << *(other.cnt);
cnt = other.cnt;
(*cnt)++;
} // Copy-constructor
int counter(){
int c = *cnt;
return c;
}
};
In main.cpp, I did the following:
int main(){
// smart_pointer_examples();
std::string h("hello");
smart_pointer<std::string> p(&h);
std::cout << "p: " << p.counter();
smart_pointer<std::string> q(p);
std::cout << ", q: " << q.counter() << std::endl;
return 0;
}
The problem is that that outputs p: 1, q: 6487781. After a lot of time trying to find the issue by debugging and printing stuff, I found something that fixed my issue: By adding std::cout << ", *(other.cnt): " << *(other.cnt); somewhere in my copy-constructor, the output becomes p: 1, *(other.cnt): 1, q: 2, which is the desired behaviour. I can't for the life of me think of why printing the counter would change anything.
Edit: Also, if I only do *(other.cnt) without std::cout, the same problem that I started with happens.
You made a small mistake in implementing your idea.
I will not comment on the design of your smart pointer implementation.
The problem is that you implemented your counter as a pointer. That is wrong.
And, you are dereferencing a local variable. That is a semantic bug. The result is undefined. The value of the counter will be indeterminate. Additionally you should initialize your class members.
If we fix both, then your code will look like:
#pragma once
#include <iostream>
template <typename T>
class smart_pointer {
T* pointer{};
int cnt{};
public:
smart_pointer<T>(T* el) : pointer(el) { cnt = 1; }; //
smart_pointer<T>(const smart_pointer<T>& other) : pointer(other.pointer) {
// std::cout << ", *(other.cnt): " << *(other.cnt);
cnt = other.cnt;
cnt++;
} // Copy-constructor
int counter() const {
return cnt;
}
};
int main() {
// smart_pointer_examples();
std::string h("hello");
smart_pointer<std::string> p(&h);
std::cout << "p: " << p.counter();
smart_pointer<std::string> q(p);
std::cout << ", q: " << q.counter() << std::endl;
return 0;
}
I'm trying to figure out how to save and load an objects state to a binary stream. For context, we currently have this working but only a 'save-to-file' implementation. However, we want the serialization done in-memory to better interact with some parallelization libraries. I'm hoping this will be quite simple but my current implementation doesn't do much - can anybody spot what I'm doing wrong?
class ForSerializationAsBinary {
public:
ForSerializationAsBinary() = default;
explicit ForSerializationAsBinary(int number)
: number_(number) {}
std::ostringstream toBinaryStream() {
std::ostringstream out(std::ios::binary);
out.write((char *) &number_, sizeof(int));
return out;
}
static void fromBinaryStream(ForSerializationAsBinary &obj, std::ostringstream &os) {
int n;
std::istringstream is(std::ios::binary);
is.basic_ios<char>::rdbuf(os.rdbuf());
is.read((char *) &n, sizeof(int));
std::cout << "n: " << n << std::endl;
obj.number_ = n;
}
int number_;
};
TEST(Serialisation, SimpleSerialization) {
ForSerializationAsBinary serializationAsBinary(4);
auto o = serializationAsBinary.toBinaryStream();
ForSerializationAsBinary loaded;
ForSerializationAsBinary::fromBinaryStream(loaded, o);
std::cout << "loaded.number_: " << loaded.number_ << std::endl;
}
And the current output of the test
n: 0
loaded.number_: 0
Looks like I found the answer : just use a std::stringstream instead of the o or i versions:
class ForSerializationAsBinary {
public:
ForSerializationAsBinary() = default;
explicit ForSerializationAsBinary(int number)
: number_(number) {}
std::stringstream toBinaryStream() {
std::stringstream out(std::ios::binary);
out.write((const char *) &number_, sizeof(int));
return out;
}
static void fromBinaryStream(ForSerializationAsBinary &obj, std::stringstream &os) {
int n;
os.read((char *) &n, sizeof(int));
std::cout << "n: " << n << std::endl;
obj.number_ = n;
}
int number_;
};
I am writing a parser for a simple programming language consisting of possibly an axis number, a two letter command, and possibly an input value. All commands are separated by a comma. I have a parser that splits the input by the delineator and runs each valid command one at a time. I'm having issues programming the looping function RP.
I could have a command like this
MD1,TP,RP5,TT,RP10
in which I would want it to run as
for (int i = 0; i < 10; i++) {
TT();
for (int j = 0; j < 5; j++) {
TP();
}
}
So far the main parser that I have will see the first RP command and run that then see the second RP command and run it. The RP command is set to loop from the end of the last RP command giving something more like this.
for (int j = 0; j < 5; j++) {
TP();
}
for (int i = 0; i < 10; i++) {
TT();
}
I've tried a few different approaches, but so far no luck. Any and all help is appreciated.
Actually, I considered the question a little bit too broad. On the other hand, I couldn't resist to "try out".
Preface
First, I want to criticize (a little bit) the question title. simple logic parser sounds for me like an interpreter of boolean expressions. However, I remember that my engineering colleagues are often talking about "program logic" (and I've not yet achieved that they get rid of this). Hence, my recommendation: If you (the questioner) are talking with computer scientists, use the term "logic" sensible (or they might look confused sometimes...)
The sample code MD1,TP,RP5,TT,RP10 looks somehow familiar to me. A short google/wikipedia research cleared my mind: The Wikipedia article Numerical control is about CNC machines. Close to the end of the article, the programming is mentioned. (The German "sibling" article provides even more.) IMHO, the code really looks similar a bit but seems to be even simpler. (No offense – I consider it as good to keep things as simple as possible.)
The program notation which seems to be intended is somehow like Reverse Polish notation. I wanted at least mention that term as googling for "rpn interpreter" throws a lot of sufficient hits including github sites. Actually, the description of the intended language is a little bit too short to decide certainly which existing S/W project could be appropriate.
Having said this, I want to show what I got...
Parser
I started first with a parser (as the questioner didn't dare to expose his). This is the code of mci1.cc:
#include <iostream>
#include <sstream>
using namespace std;
typedef unsigned char uchar;
enum Token {
TkMD = 'M' | 'D' << 8,
TkRP = 'R' | 'P' << 8,
TkTP = 'T' | 'P' << 8,
TkTT = 'T' | 'T' << 8
};
inline Token tokenize(uchar c0, uchar c1) { return (Token)(c0 | c1 << 8); }
bool parse(istream &in)
{
for (;;) {
// read command (2 chars)
char cmd[2];
if (in >> cmd[0] >> cmd[1]) {
//cout << "DEBUG: token: " << hex << tokenize(cmd[0], cmd[1]) << endl;
switch (tokenize(cmd[0], cmd[1])) {
case TkMD: { // MD<num>
int num;
if (in >> num) {
cout << "Received 'MD" << dec << num << "'." << endl;
} else {
cerr << "ERROR: Number expected after 'MD'!" << endl;
return false;
}
} break;
case TkRP: { // RP<num>
int num;
if (in >> num) {
cout << "Received 'RP" << dec << num << "'." << endl;
} else {
cerr << "ERROR: Number expected after 'RP'!" << endl;
return false;
}
} break;
case TkTP: // TP
cout << "Received 'TP'." << endl;
break;
case TkTT: // TT
cout << "Received 'TT'." << endl;
break;
default:
cerr << "ERROR: Wrong command '" << cmd[0] << cmd[1] << "'!" << endl;
return false;
}
} else {
cerr << "ERROR: Command expected!" << endl;
return false;
}
// try to read separator
char sep;
if (!(in >> sep)) break; // probably EOF (further checks possible)
if (sep != ',') {
cerr << "ERROR: ',' expected!" << endl;
return false;
}
}
return true;
}
int main()
{
// test string
string sample("MD1,TP,RP5,TT,RP10");
// read test string
istringstream in(sample);
if (parse(in)) cout << "Done." << endl;
else cerr << "Interpreting aborted!" << endl;
// done
return 0;
}
I compiled and tested with g++ and bash in Cygwin on Windows 10:
$ g++ --version
g++ (GCC) 6.4.0
$ g++ -std=c++11 -o mci mci1.cc
$ ./mci
Received 'MD1'.
Received 'TP'.
Received 'RP5'.
Received 'TT'.
Received 'RP10'.
Done.
$
Uploaded for life demo on ideone.
I introduced the function tokenize() as part of an update. (I got the idea when I was tooth brushing and poring how to get rid of the ugly nested switches of the previous version.) Tokenizing is a common technique in parsing – however, the implementation is usually a little bit different.
Thus, the parser seems to work. Not yet the next big thing but sufficient for the next step...
Interpreter
To interprete the parsed commands, I started to make a resp. back-end – a set of classes which may store and execute the required operations.
The parse() function of the first step became the compile() function where simple standard output was replaced by code building and nesting the operations. mci2.cc:
#include <cassert>
#include <iostream>
#include <stack>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
// super class of all operations
class Op {
protected:
Op() = default;
public:
virtual ~Op() = default;
virtual void exec() const = 0;
// disabled: (to prevent accidental usage)
Op(const Op&) = delete;
Op& operator=(const Op&) = delete;
};
// super class of grouping operations
class Grp: public Op {
protected:
vector<Op*> _pOps; // nested operations
protected:
Grp() = default;
virtual ~Grp()
{
for (Op *pOp : _pOps) delete pOp;
}
public:
void add(Op *pOp) { _pOps.push_back(pOp); }
// disabled: (to prevent accidental usage)
Grp(const Grp&) = delete;
Grp& operator=(const Grp&) = delete;
};
// class for repeat op.
class RP: public Grp {
private:
unsigned _n; // repeat count
public:
RP(unsigned n): Grp(), _n(n) { }
virtual ~RP() = default;
virtual void exec() const
{
cout << "Exec. RP" << _n << endl;
for (unsigned i = 0; i < _n; ++i) {
for (const Op *pOp : _pOps) pOp->exec();
}
}
// disabled: (to prevent accidental usage)
RP(const RP&) = delete;
RP& operator=(const RP&) = delete;
};
// class for TP op.
class TP: public Op {
public:
TP() = default;
virtual ~TP() = default;
virtual void exec() const
{
cout << "Exec. TP" << endl;
}
};
// class for TT op.
class TT: public Op {
public:
TT() = default;
virtual ~TT() = default;
virtual void exec() const
{
cout << "Exec. TT" << endl;
}
};
// class for MD sequence
class MD: public Grp {
private:
unsigned _axis;
public:
MD(unsigned axis): Grp(), _axis(axis) { }
virtual ~MD() = default;
virtual void exec() const
{
cout << "Exec. MD" << _axis << endl;
for (const Op *pOp : _pOps) pOp->exec();
}
};
typedef unsigned char uchar;
enum Token {
TkMD = 'M' | 'D' << 8,
TkRP = 'R' | 'P' << 8,
TkTP = 'T' | 'P' << 8,
TkTT = 'T' | 'T' << 8
};
inline Token tokenize(uchar c0, uchar c1) { return (Token)(c0 | c1 << 8); }
MD* compile(istream &in)
{
MD *pMD = nullptr;
stack<Op*> pOpsNested;
#define ERROR \
delete pMD; \
while (pOpsNested.size()) { delete pOpsNested.top(); pOpsNested.pop(); } \
return nullptr
for (;;) {
// read command (2 chars)
char cmd[2];
if (in >> cmd[0] >> cmd[1]) {
//cout << "DEBUG: token: " << hex << tokenize(cmd[0], cmd[1]) << dec << endl;
switch (tokenize(cmd[0], cmd[1])) {
case TkMD: { // MD<num>
int num;
if (in >> num) {
if (pMD) {
cerr << "ERROR: Unexpected command 'MD" << num << "'!" << endl;
ERROR;
}
pMD = new MD(num);
} else {
cerr << "ERROR: Number expected after 'MD'!" << endl;
ERROR;
}
} break;
case TkRP: { // RP<num>
int num;
if (in >> num) {
if (!pMD) {
cerr << "ERROR: Unexpected command 'RP" << num << "'!" << endl;
ERROR;
}
RP *pRP = new RP(num);
while (pOpsNested.size()) {
pRP->add(pOpsNested.top());
pOpsNested.pop();
}
pOpsNested.push(pRP);
} else {
cerr << "ERROR: Number expected after 'RP'!" << endl;
ERROR;
}
} break;
case TkTP: { // TP
if (!pMD) {
cerr << "ERROR: Unexpected command 'TP'!" << endl;
ERROR;
}
pOpsNested.push(new TP());
} break;
case TkTT: { // TT
if (pOpsNested.empty()) {
cerr << "ERROR: Unexpected command 'TT'!" << endl;
ERROR;
}
pOpsNested.push(new TT());
} break;
default:
cerr << "ERROR: Wrong command '" << cmd[0] << cmd[1] << "'!" << endl;
ERROR;
}
} else {
cerr << "ERROR: Command expected!" << endl;
ERROR;
}
// try to read separator
char sep;
if (!(in >> sep)) break; // probably EOF (further checks possible)
if (sep != ',') {
cerr << "ERROR: ',' expected!" << endl;
ERROR;
}
}
#undef ERROR
assert(pMD != nullptr);
while (pOpsNested.size()) {
pMD->add(pOpsNested.top());
pOpsNested.pop();
}
return pMD;
}
int main()
{
// test string
string sample("MD1,TP,RP3,TT,RP2");
// read test string
istringstream in(sample);
MD *pMD = compile(in);
if (!pMD) {
cerr << "Interpreting aborted!" << endl;
return 1;
}
// execute sequence
pMD->exec();
delete pMD;
// done
return 0;
}
Again, I compiled and tested with g++ and bash in Cygwin on Windows 10:
$ g++ -std=c++11 -o mci mci2.cc
$ ./mci
Exec. MD1
Exec. RP2
Exec. TT
Exec. RP3
Exec. TP
Exec. TP
Exec. TP
Exec. TT
Exec. RP3
Exec. TP
Exec. TP
Exec. TP
$
Uploaded for life demo on ideone.
The trick with the nesting is rather simple done in the compile() function:
commands TP and TT are added to a temporary stack pOpsNested
for command RP, all collected operations are added to the RP instance popping the pOpsNested stack (and thus reversing their order),
afterwards, the RP instance itself is pushed into pOpsNested stack instead
finally the contents of buffer pOpsNested is added to sequence MD (as these are the top-level ops).
This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 7 years ago.
I have been attempting to create a function getLocation() that utilizes a pointer to return the value of the struct Location declared in the Character class. I was curious as to the problem with my syntax (or my structure). Knowing that the asterisk * should refer to the value, why is it that my function using an ampersand string& Character::getInventory is able to return the value of that particular index (its return does not need to be converted)?
Trying Location& Character::getLocation() {return position; }
when run results in error C2679: binary '<<': no operator found
Nor
Location*
Which cannot be run as there is no conversion.
I read that the following is likely the most proper because it specifies the scope in which the structure resides, but still results in needing and returning a temporary.
Character::Location* const & Character::getLocation() {return &position; }
Any advice or input would be greatly appreciated, thanks in advance.
Below is my main.cpp, which of course will show the hexadecimal address for Location.
#include <iostream>
#include <string>
using std::cerr;
using std::cin;
using std::cout;
using std::endl;
using std::string;
class Character {
private:
string name;
string inventory[4];
public:
struct Location {
int x; int y;
};
Location position;
public:
void Character::setName(string x) { name = x; }
string Character::getName() { return name; }
void Character::setLocation(int x, int y) {
position.x = x; position.y = y;
}
Location* Character::getLocation() {return &position; }
void Character::setInventory(string(&x)[4]) { for (int i = 0; i < 4; ++i) { inventory[i] = x[i]; } }
string& Character::getInventory(int itemNumber) { return inventory[itemNumber]; }
};
void showUser(Character Character);
int main() {
try {
string items[4] = { "Sword", "Shield", "Potion", "Cloak" };
Character CharacterI;
CharacterI.setName("Some Character");
CharacterI.setInventory(items);
CharacterI.setLocation(1, 30);
cout << "\n" << "Retrieving Character Info..." << "\n" << endl;
showUser(CharacterI);
}
catch (std::exception & e) {
cerr << "\nError : " << e.what() << '\n';
}
system("pause");
return 0;
}
void showUser(Character character) {
cout << "Name : " << character.getName() << endl;
cout << "Location : " << character.getLocation() << endl;
for (int i = 0; i < 4; ++i) {
cout << "Inventory " << i + 1 << " : " << character.getInventory(i) << endl;
}
}
Ok, I think I understand the question better now. The reason why getInventory can successfully return a reference while getLocation does not is because getLocation returns a reference to a temporary variable, which is not good. See the link in #NathanOliver's comment for details. Additionally, to paraphrase a previous comment by #Peter Schneider, an * in an expression dereferences a pointer to return a value, while in a declaration it signifies that a variable will be of pointer type. The two usages are more or less opposites of each other. Example:
int* p = new int; //Declares a pointer to int
int x = *p; //Dereferences a pointer and returns an int
What you need to do is create a member variable to hold the Character's location, then set/get from that variable instead of creating temporaries. You did this already for name and inventory, just keep using that same pattern.
Additionally, whenever you use the Location struct outside of the Character class scope, you need to fully-qualify it with Character::Location.
Example:
#include <iostream>
using namespace std;
class Character {
public:
struct Location {
int x;
int y;
};
Location loc;
void SetLocation(int x, int y) {loc.x = x; loc.y = y;}
Location& GetLocation() {return loc;}
};
int main ()
{
Character c;
c.SetLocation(1,42);
Character::Location l = c.GetLocation();
cout << l.x << endl << l.y << endl;
return 0;
}
Output:
1
42
I have the following code in a class member function:
int state = 0;
int code = static_cast<int>(letter_[i]);
if (isalnum(code)) {
state = testTable[state][0];
} else if (isspace(code)) {
state = testTable[state][2];
} else if (code == OPEN_TAG) {
state = testTable[state][3];
} else if (code == CLOSE_TAG) {
state = testTable[state][4];
} else {
state = testTable[state][1];
}
switch (state) {
case 1: // alphanumeric symbol was read
buffer[j] = letter_[i];
++j;
break;
case 2: // delimeter was read
j = 0;
// buffer.clear();
break;
}
However, if state is a class member variable rather than local, the performance drops considerably (~ 5 times). I was reading about differences in accessing local variables and class members, but texts usually say that it affects performance very slightly.
If it helps: I am using MinGW GCC compiler with -O3 option.
I could not reproduce your observation, testing on x86_64 with both, VS10 and g++. The local variant is slightly faster, probably due to what Alan Stokes described in his comment, but at most ~10%. You should check your timing, try to rule out any other problems and best would be the reduce all your code to a very simple test-cast which still shows this behavior.
I think my test-case resembles your scenario quite good, at least like you described it:
#include <iostream>
#include <boost/timer.hpp>
const int max_iter = 1<<31;
const int start_value = 65535;
struct UseMember
{
int member;
void foo()
{
for(int i=0; i<max_iter; ++i)
{
if(member%2)
member = 3*member+1;
else
member = member>>1;
}
std::cout << "Value=" << member << std::endl;
}
};
struct UseLocal
{
void foo()
{
int local = start_value;
for(int i=0; i<max_iter; ++i)
{
if((local%2)!=0) /* odd */
local = 3*local+1;
else /* even */
local = local>>1;
}
std::cout << "Value=" << local << std::endl;
}
};
int main(int argc, char* argv[])
{
/* First, test using member */
std::cout << "** Member Access" << std::endl;
{
UseMember bar;
bar.member = start_value;
boost::timer T;
bar.foo();
double e = T.elapsed();
std::cout << "Time taken: " << e << "s" << std::endl;
}
/* Then, test using local */
std::cout << "** Local Access" << std::endl;
{
UseLocal bar;
boost::timer T;
bar.foo();
double e = T.elapsed();
std::cout << "Time taken: " << e << "s" << std::endl;
}
return 0;
}