std string gets corrupted inside class - c++

I am experimenting with building a simple nodegraph library for some projects i have in mind, but i'm hitting what i hope is a really simple roadblock very early on but it has me stumped.
I define objects called NodeDefinitions which are recipes from which nodes can be created in pre-defined configuraitons (number of ports/parameters etc.). NodeDefinition object contains PortDefinition objects that define each of the input/output ports. These PortDefinition objects contain their name (along with some other information in my full code, although removed below for brevity).
My Node class has a Node() constructor that creates a Node given a NodeDefition object. When I use this I create Port objects that each contain a pointer to their corresponding PortDefinition. When I try and print out the name of the port (derived from/stored in the PortDefinition object) it gets corrupted.
Through a little trial and error i have managed to find that if i just pass a std::vector directly to an alternate Node() constructor, then everything appears to work fine.
In the example code below i'm printing out the port names (only one port here), both inside the constructor and then after in the caller.
The definition classes.
class PortDefinition
{
public:
PortDefinition(const std::string & name) : m_name(name)
{}
std::string m_name;
};
class NodeDefinition
{
public:
NodeDefinition(std::vector<PortDefinition> portDefinitions) :
m_portDefinitions(portDefinitions)
{}
std::vector<PortDefinition> m_portDefinitions;
};
The concrete object classes.
class Port
{
public:
Port(PortDefinition * portDefinition) :
m_portDefinition(portDefinition)
{}
const PortDefinition * m_portDefinition;
};
class Node
{
public:
Node(NodeDefinition nodeDefinition) {
std::vector<PortDefinition> portDefs = nodeDefinition.m_portDefinitions;
for (auto & it : portDefs) {
Port newPort = Port( &it );
m_ports.push_back( newPort );
}
print();
}
Node(std::vector<PortDefinition> portDefs) {
for (auto & it : portDefs) {
Port newPort = Port( &it );
m_ports.push_back( newPort );
}
print();
}
void print() const {
std::cout << m_ports.size() << " : ";
for (auto it : m_ports) {
std::cout << "'" << it.m_portDefinition->m_name << "'" << std::endl;
}
}
private:
std::vector<Port> m_ports;
};
The test code.
int main (int argc, const char *argv[])
{
std::vector<PortDefinition> portDefinitions;
portDefinitions.push_back( PortDefinition("Port_A") );
NodeDefinition nodeDefinition = NodeDefinition(portDefinitions);
std::cout << "constuctor N1 : ";
Node N1 = Node(nodeDefinition);
std::cout << "main func N1 : ";
N1.print();
std::cout << std::endl;
std::cout << "constuctor N2 : ";
Node N2 = Node(portDefinitions);
std::cout << "main func N2 : ";
N2.print();
return 1;
}
All of the code can be compiled in a single file together.
When I run this get the following output.
constuctor N1 : 1 : 'Port_A'
main func N1 : 1 : ''
constuctor N2 : 1 : 'Port_A'
main func N2 : 1 : 'Port_A'
As you can see when i print out the port name after using the Node() constructor that uses the NodeDefinition object the name is empty, sometimes I get garbage there instead, which makes me think something is corrupting memory somehow, but i'm a bit lost as to why.

std::vector<PortDefinition> portDefs = nodeDefinition.m_portDefinitions;
for (auto & it : portDefs) {
Port newPort = Port( &it );
m_ports.push_back( newPort );
}
This code is the problem. portDefs is a copy of nodeDefinition.m_portDefinitions, being destroyed when the constructor is finished. But you store a pointer to the these objects with Port(&it).
The print() in the constructor should work fine, but the print() in main now accesses the destroyed copies, which is undefined behaviour.
A possible solution would be to store shared_ptr of your PortDefinition or just store a copy in Port.

Related

How to get value from a vector by value from another vector?

I have two vectors:
one contains numbers and names of things;
second collects numbers that have already been showed to the user;
I'm trying to make a history list of all objects that have been shown.
Here is my code:
class palettArchive{
private:
std::vector<std::pair<int,std::string>> paletts;
int palletsCounter;
std::vector<int> choosen;
public:
//...
void history(){
auto printHist = [](int& i){
int tmp = i;
std::pair<int,std::string> tempPair = paletts[tmp];
std::cout << tempPair.first << " " << tempPair.second;
return 0;
};
std::for_each(choosen.begin(), choosen.end(), printHist);
}
};
There is an error:
error: 'this' cannot be implicitly captured in this context
std::pair<int,std::string> tempPair = paletts[tmp];
I can't make a third vector with the list that is created already. I need to make it by calling a function and printing at the time.
The lambda must capture this to be able to access member variables:
auto printHist = [this](int& i){ ... };
for_each and lambda are just making your life difficult. The simpler code is explicit iteration:
void history()
{
for (auto i : choosen) {
auto tempPair = paletts[i];
std::cout << tempPair.first << " " << tempPair.second;
// did you mean to send a newline "\n" also?
}
}

Segmentation fault for calling base class variable

I have been using this code for a long time now in a project. However, I have recently added llvm-config --cxxflags --libs to the compiler in order to link with llvm libraries and it started generating seg faults. I have located the error and it happens when I call base class's variables.
Here is a small example of what I a doing
in Literals.hh
class LiteralObj : public RuleObj {
public:
LiteralObj();
LiteralObj(char *str);
~LiteralObj();
std::string raw_value;
static int literalobj_cnt;
int literalobj_id;
};
class LiteralIntObj : public LiteralObj{
public:
LiteralIntObj();
LiteralIntObj(char *str);
~LiteralIntObj();
void graphVis(std::ofstream &ofs, std::string &srcRef);
CODE_GENERATION;
int value;
};
Literals.cc
LiteralObj::LiteralObj() : RuleObj(){
ENTER_STATEMENT
raw_value = "";
literalobj_id = literalobj_cnt;
literalobj_cnt++;
}
LiteralObj::LiteralObj(char *str) : RuleObj(){
ENTER_STATEMENT
std::cerr << ruleobj_id << "\n";
raw_value = str;
literalobj_id = literalobj_cnt;
literalobj_cnt++;
}
LiteralObj::~LiteralObj()
{
ENTER_STATEMENT;
}
LiteralIntObj::LiteralIntObj() : LiteralObj()
{
ENTER_STATEMENT;
value = 0;
}
LiteralIntObj::LiteralIntObj(char *str) : LiteralObj(str)
{
ENTER_STATEMENT;
std::cerr << ruleobj_id << '\n';
value = stoi(raw_value);
}
LiteralIntObj::~LiteralIntObj()
{
ENTER_STATEMENT;
}
void LiteralIntObj::graphVis(std::ofstream &ofs, std::string &srcRef) {
ENTER_GRAPHVIS;
// -- define names
std::string currRef = "LiteralIntObj";
std::string name = "LiteralInt";
std::cerr << raw_value << "\n";
//it crashes here with SEGFAULT.
}
The code prints out raw_value of the base class fine for the first object, but, when the second is called SEGMENTATION Fault is generated.
When i changed compile options the pointers were set to 0xfffffff by default instead of 0. Therefore the check if (pointer) generated true even when the pointer were not initialized that led to calling function graphViz().

Dynamic variable doesnt work

in this code why does the first("invNummer") is always 0, when I initializate it dynamically? When I do it as a static(two) it works.
class Computer {
private:
int invNummer;
char* osName;
int state; // 0 – aus, 1 - an
public:
Computer(int INV, char* OS, int st);
void info() {
cout << invNummer << " " << osName << " " << state << endl;
}
};
Computer::Computer(int INV, char* OS, int st)
: invNummer(INV)
, osName(OS)
, state(st)
{};
int main()
{
Computer* one;
one = new Computer(10, (char*)"Windows", 1);
delete one;
Computer two(9, (char*)"Linux", 0);
one->info();
two.info();
return 0;
}
Output looks like this:
0 Windows 1
9 Linux 0
As #It's_comming_home pointed out to you, your issue is not related to creating the one object dynamically, but to the deletion of that object:
delete one;
When you delete the one object, the pointer is left dangling, ie it is no longer usable. If you try to dereference it afterwards:
one->info();
You will get undefined behavior, like your output shows.
To fix this, just move the deletion of the one object after you invoke its info() method:
one->info();
two.info();
delete one;

Lua_hook and lua_Debug->event

I'm trying to learn lua and building a virtual machine in c++, I want to write a debugging class, to make my life easier. I'm actually blocked because I don't understand how the callbacks are done, here is my code :
//Im here adding my fct to a global map.
void Debugger::setFctHook(void)
{
g_hookers[LUA_MASKCALL] = HookCall;
g_hookers[LUA_MASKRET] = HookRet;
g_hookers[LUA_HOOKTAILRET] = HookRet;
g_hookers[LUA_MASKLINE] = HookLine;
g_hookers[LUA_MASKCOUNT] = HookCount;
}
Here is my constructor :
Debugger::Debugger(VirtualMachine &vm, uint count)
: VM_(vm), count_(count)
{
setFctHook();
if (vm.isFonctionnal())
{
vm.addDebugger(this);
lua_sethook(vm.getLua(), HookEvents, 0, count_);
}
}
and my setter :
void Debugger ::setHook(int hookMask) const
{
std::cout << hookMask << "SETHOOOOOOOOOK" << std::endl;
lua_sethook(VM_.getLua(), HookEvents, hookMask, count_);
}
Here is my Central hook :
static void HookEvents(lua_State *lua, lua_Debug *debug)
{
std::map<int, fctHook>::iterator it;
std::cout << debug->event << std::endl;
it = g_hookers.find(debug->event);
if (it != g_hookers.end())
{
std::cout << "First: " << it->first << std::endl;
it->second(lua);
}
}
The problem is that the value show in my setter differs from the value printed in my central function hook, I tried many defines and I dont see any logic in the different values.
Result :
8 SETHOOOOOOOOOK // received on my setter.
3 // received on my central hook
I solved my problem, the problem is that my map has bad values on it, the correct defines for the hooks are :
void Debugger::setFctHook(void)
{
g_hookers[LUA_HOOKCALL] = HookCall;
g_hookers[LUA_HOOKRET] = HookRet;
g_hookers[LUA_HOOKTAILRET] = HookRet;
g_hookers[LUA_HOOKLINE] = HookLine;
g_hookers[LUA_HOOKCOUNT] = HookCount;
}

Making an event like subscribing system for C++ * chars

For simple data like ints or constants something like this would work
#include <iostream>
#include <vector>
using namespace std ;
typedef void FuncInt (int) ;
class GraphElementProto {
public:
void add (FuncInt* f)
{
FuncVec.push_back (f) ;
} ;
void call()
{
for (size_t i = 0 ; i < FuncVec.size() ; i++)
FuncVec[i] (i) ;
} ;
private:
vector<FuncInt*> FuncVec ;
} ;
static void f0 (int i) { cout << "f0(" << i << ")" << endl ; }
static void f1 (int i) { cout << "f1(" << i << ")" << endl ; }
int main() {
GraphElementProto a ;
a.add (f0) ;
a.add (f1) ;
a.call() ;
}
So now imagine we work with some data buffer like char.
We have threads that wait for data pointers and on appearance of that pointers want to change data at the same time. So we would need to create copy's of that data and give to each subscriber pointer to his own copy.
So how to do such thing? (sorry C++ nube - code is only thing I can understand)
Consider the similarities between each node of the graph that you describe and create a class for them (class GraphElement below). It should encapsulate its relationship to its child nodes, and it should do something locally with any incoming messages (function localAction). You should then derive classes that represent specific variations - such as the image generator you mention - and change the local action. Each class may take a copy of the original message, or change it as you need.
In my example code here I have create the default graph node - GraphNode - and made it simply print incoming messages before passing them to its child nodes. I have used a string object for the incoming message - a lot nicer than a plain old C char * array [example: you can derive a string from char * when message2 is created in the code below]. I have made those object const references as its cheap, fast, and never changes the original.
I have derived a class called CatNode as an example of the variation you need. Objects of this type contain a history of all messages, and print out that history when a new message arrives. Not very useful - but a good example none the less. This demonstrates how each node may do anything to a copy of the original message - rewrite localAction(). It also passes that history to any child nodes - rewrite incomingMessage with a change to the parameter passed to deliverMessage().
#include <vector>
#include <iostream>
#include <string>
using std::cout;
using std::endl;
using std::vector;
using std::string;
class GraphNode
{
public:
GraphNode( string & name ) : mChildren(), mName(name) {}
GraphNode( const char * const name ) : mChildren(), mName(name==NULL?"":name) {}
virtual void incomingMessage( const string & str ) {
localAction(str); // This node is to do something.
deliverMessage(str); // Child nodes are to do things too.
}
void addChild( GraphNode * child ) {
mChildren.push_back( child );
}
protected:
// Rewrite this function for child classes who are to do different things with messages.
virtual void localAction( const string & str ) {
cout << mName << " : " << str << endl;
}
void deliverMessage( const string & str ) {
vector<GraphNode*>::iterator itr = mChildren.begin();
for( ; itr != mChildren.end(); ++itr )
(*itr)->incomingMessage(str);
}
// Data members
vector<GraphNode*> mChildren;
string mName;
}; // [ GraphNode ]
class CatNode : public GraphNode
{
public:
CatNode( string & name ) : GraphNode(name), mHistory() {}
CatNode( const char * const name ) : GraphNode(name), mHistory() {}
virtual void incomingMessage( const string & str ) {
localAction(str);
deliverMessage(mHistory);
}
protected:
virtual void localAction( const string & str ) {
mHistory += str;
cout << mName << " : " << mHistory << endl;
}
// Data members
string mHistory;
}; // [ CatNode ]
main()
{
// root -> childA
GraphNode root("Root Node");
CatNode childA("Child A");
root.addChild( &childA );
root.incomingMessage("Message1");
cout << endl;
// root -> childA -> childC
// \-> childB
GraphNode childB("Child B");
root.addChild( &childB );
GraphNode childC("Child C");
childA.addChild( &childC );
string message2("Message2");
root.incomingMessage(message2);
} // [ main ]