I would like to know the best/correct way to get back to the initial values of an object without playing with delete and new (everything must stay on the stack)
With this 2 classes:
static const int defaultValue{15};
class Foo
{
private:
int val1{defaultValue};
short val2{4};
}
class LongStandingObject
{
public:
void resetFoo(int index);
private:
Foo foos[100];
}
If I need to reset some foos to their default values, what is the best way?
Create reset method in Foo
void Foo::reset()
{
val1 = defaultValue;
val2 = 4;
}
I don't really like the idea to have the values coming from 2 differents places and I do like to have the defaults values in the header next to the variable declaration.
Replace by a locally created Foo
void LongStandingObject::resetFoo(int index)
{
foos[index] = Foo();
}
Am I heading to trouble when the local variable is destroyed?
Use memcpy
void LongStandingObject::resetFoo(int index)
{
Foo foo;
memcpy(foos[index], &foo, sizeof(Foo));
}
Maybe less readable...
Any other method?
Your #2 is just fine, and probably the most legible.
void LongStandingObject::resetFoo(int index)
{
foos[index] = Foo();
}
There are no object lifetime issues here: the assignment operator is called on foos[index] to change its values to match the temporary object materialized from Foo(). That is, the code is exactly equivalent to
{
Foo tmp;
foos[index].val1 = tmp.val1;
foos[index].val2 = tmp.val2;
}
And if optimizations are enabled, almost any compiler will be able to just modify foos[index] directly without actually creating the temporary Foo.
If you do want a Foo::reset() function as well, you can use the same idea for it:
void Foo::reset()
{
*this = Foo();
}
I would avoid using memcpy, since the program would become incorrect if you ever make changes to Foo that make it no longer trivially copyable.
What you can do is to use std::pair on each variable. Initialized with with variable.first = variable.second = value. After, every time you want to update the variable you set: variable.second = new_value. When you want to restore to the original, you set: variable.second = variable.first. You can improve it by writing a macro RestoreDefault(var) to make the code more readable.
For example:
#define RestoreDefault(var) ((var).second = (var).first)
// int val1{180}; // Instead of this line
std::pair<int,int> val1{ 180,180}; // <- this line
val1.second = 456;
RestoreDefault(val1);
If you want to hardcoded block any possibility to re-set later the default value, write:
std::pair<const int,int> val1{ 180,180}; // <- this line
-
Addition: Same principle for array:
class Foo
{
public:
int x = 100;
int y = 200;
};
#define RestoreArrDefault(var) ((var).second.fill((var).first))
// Use:
std::pair<Foo, std::array<Foo, 100>> FooAr, FooAr2;
// You can define different arrays with different defaults:
FooAr.first = { 180,360 }; // <- Customize FooAr defaults
// In that point FooAr default is 180,360 and FooAr2 default is 100,200
FooAr.second[3] = { 2,10 }; // <- Edit FooAr index-3 item
RestoreArrDefault(FooAr); // <- Restore Default
Related
From /snap/dlang/43/usr/include/dlang/dmd/std/process.d:
string[string] toAA() #trusted
{
import std.conv : to;
string[string] aa;
version (Posix)
{
auto environ = getEnvironPtr;
for (int i=0; environ[i] != null; ++i)
{
import std.string : indexOf;
immutable varDef = to!string(environ[i]);
immutable eq = indexOf(varDef, '=');
assert(eq >= 0);
immutable name = varDef[0 .. eq];
immutable value = varDef[eq+1 .. $];
// In POSIX, environment variables may be defined more
// than once. This is a security issue, which we avoid
// by checking whether the key already exists in the array.
// For more info:
// http://www.dwheeler.com/secure-programs/Secure-Programs-HOWTO/environment-variables.html
if (name !in aa) aa[name] = value;
}
}
// ...
}
But getEnvironPtr() is defined as follows:
extern(C) extern __gshared const char** environ;
const(char**) getEnvironPtr() #trusted
{
return environ;
}
The above code seems for me beign not thread safe because of use __gshared and the fact that environ extern variable is modifyable. Is this a bug in D? Or what may I misunderstand?
This is the only way to do it in Posix. The variable is marked const, so you can't modify it, but you can declare another extern(C) variable that can modify the same memory. So don't do that.
D does a lot to make things safe, but the only way to make this truly safe would be to eliminate extern(C). Or to get rid of Posix and rebuild an OS from scratch in D. Those are both drastic measures disproportionate to the size of the problem.
ALL,
I have a class defined that just holds the data (different types of data). I also have std::vector that holds a pointers to objects of this class.
Something like this:
class Foo
{
};
class Bar
{
private:
std::vector<Foo *> m_fooVector;
};
At one point of time in my program I want to remove an element from this vector. And so I write following:
for (std::vector<Foo *>::iterator it = m_fooVector.begin(); it <= m_fooVector.end(); )
{
if( checking it condition is true )
{
delete (*it);
(*it) = NULL;
m_fooVector.erase( it );
}
}
The problem is that the erase operation fails. When I open the debugger I still see this element inside the vector and when the program finishes it crashes because the element is half way here.
In another function I am trying to remove the simple std::wstring from the vector and everything works fine - string is removed and the size of the vector decreased.
What could be the problem for such behavior? I could of course try to check the erase function in MSVC standard library, but I don't even know where to start.
TIA!!!
Your loop is incorrect:
for (std::vector<Foo *>::iterator it = m_fooVector.begin(); it != m_fooVector.end(); )
{
if (/*checking it condition is true*/)
{
delete *it;
// *it = NULL; // Not needed
it = m_fooVector.erase(it);
} else {
++it;
}
}
Traditional way is erase-remove idiom, but as you have to call delete first (smart pointer would avoid this issue), you might use std::partition instead of std::remove:
auto it = std::partition(m_fooVector.begin(), m_fooVector.end(), ShouldBeKeptFunc);
for (std::vector<Foo *>::iterator it = m_fooVector.begin(); it != m_fooVector.end(); ++it) {
delete *it;
}
m_fooVector.erase(it, m_fooVector.end());
first of all I admit I'm a newbie in C++ addons for node.js.
I'm writing my first addon and I reached a good result: the addon does what I want. I copied from various examples I found in internet to exchange complex data between the two languages, but I understood almost nothing of what I wrote.
The first thing scaring me is that I wrote nothing that seems to free some memory; another thing which is seriously worrying me is that I don't know if what I wrote may helps or creating confusion for the V8 garbage collector; by the way I don't know if there are better ways to do what I did (iterating over js Object keys in C++, creating js Objects in C++, creating Strings in C++ to be used as properties of js Objects and what else wrong you can find in my code).
So, before going on with my job writing the real math of my addon, I would like to share with the community the nan and V8 part of it to ask if you see something wrong or that can be done in a better way.
Thank you everybody for your help,
iCC
#include <map>
#include <nan.h>
using v8::Array;
using v8::Function;
using v8::FunctionTemplate;
using v8::Local;
using v8::Number;
using v8::Object;
using v8::Value;
using v8::String;
using Nan::AsyncQueueWorker;
using Nan::AsyncWorker;
using Nan::Callback;
using Nan::GetFunction;
using Nan::HandleScope;
using Nan::New;
using Nan::Null;
using Nan::Set;
using Nan::To;
using namespace std;
class Data {
public:
int dt1;
int dt2;
int dt3;
int dt4;
};
class Result {
public:
int x1;
int x2;
};
class Stats {
public:
int stat1;
int stat2;
};
typedef map<int, Data> DataSet;
typedef map<int, DataSet> DataMap;
typedef map<float, Result> ResultSet;
typedef map<int, ResultSet> ResultMap;
class MyAddOn: public AsyncWorker {
private:
DataMap *datas;
ResultMap results;
Stats stats;
public:
MyAddOn(Callback *callback, DataMap *set): AsyncWorker(callback), datas(set) {}
~MyAddOn() { delete datas; }
void Execute () {
for(DataMap::iterator i = datas->begin(); i != datas->end(); ++i) {
int res = i->first;
DataSet *datas = &i->second;
for(DataSet::iterator l = datas->begin(); l != datas->end(); ++l) {
int dt4 = l->first;
Data *data = &l->second;
// TODO: real population of stats and result
}
// test result population
results[res][res].x1 = res;
results[res][res].x2 = res;
}
// test stats population
stats.stat1 = 23;
stats.stat2 = 42;
}
void HandleOKCallback () {
Local<Object> obj;
Local<Object> res = New<Object>();
Local<Array> rslt = New<Array>();
Local<Object> sts = New<Object>();
Local<String> x1K = New<String>("x1").ToLocalChecked();
Local<String> x2K = New<String>("x2").ToLocalChecked();
uint32_t idx = 0;
for(ResultMap::iterator i = results.begin(); i != results.end(); ++i) {
ResultSet *set = &i->second;
for(ResultSet::iterator l = set->begin(); l != set->end(); ++l) {
Result *result = &l->second;
// is it ok to declare obj just once outside the cycles?
obj = New<Object>();
// is it ok to use same x1K and x2K instances for all objects?
Set(obj, x1K, New<Number>(result->x1));
Set(obj, x2K, New<Number>(result->x2));
Set(rslt, idx++, obj);
}
}
Set(sts, New<String>("stat1").ToLocalChecked(), New<Number>(stats.stat1));
Set(sts, New<String>("stat2").ToLocalChecked(), New<Number>(stats.stat2));
Set(res, New<String>("result").ToLocalChecked(), rslt);
Set(res, New<String>("stats" ).ToLocalChecked(), sts);
Local<Value> argv[] = { Null(), res };
callback->Call(2, argv);
}
};
NAN_METHOD(AddOn) {
Local<Object> datas = info[0].As<Object>();
Callback *callback = new Callback(info[1].As<Function>());
Local<Array> props = datas->GetOwnPropertyNames();
Local<String> dt1K = Nan::New("dt1").ToLocalChecked();
Local<String> dt2K = Nan::New("dt2").ToLocalChecked();
Local<String> dt3K = Nan::New("dt3").ToLocalChecked();
Local<Array> props2;
Local<Value> key;
Local<Object> value;
Local<Object> data;
DataMap *set = new DataMap();
int res;
int dt4;
DataSet *dts;
Data *dt;
for(uint32_t i = 0; i < props->Length(); i++) {
// is it ok to declare key, value, props2 and res just once outside the cycle?
key = props->Get(i);
value = datas->Get(key)->ToObject();
props2 = value->GetOwnPropertyNames();
res = To<int>(key).FromJust();
dts = &((*set)[res]);
for(uint32_t l = 0; l < props2->Length(); l++) {
// is it ok to declare key, data and dt4 just once outside the cycles?
key = props2->Get(l);
data = value->Get(key)->ToObject();
dt4 = To<int>(key).FromJust();
dt = &((*dts)[dt4]);
int dt1 = To<int>(data->Get(dt1K)).FromJust();
int dt2 = To<int>(data->Get(dt2K)).FromJust();
int dt3 = To<int>(data->Get(dt3K)).FromJust();
dt->dt1 = dt1;
dt->dt2 = dt2;
dt->dt3 = dt3;
dt->dt4 = dt4;
}
}
AsyncQueueWorker(new MyAddOn(callback, set));
}
NAN_MODULE_INIT(Init) {
Set(target, New<String>("myaddon").ToLocalChecked(), GetFunction(New<FunctionTemplate>(AddOn)).ToLocalChecked());
}
NODE_MODULE(myaddon, Init)
One year and half later...
If somebody is interested, my server is up and running since my question and the amount of memory it requires is stable.
I can't say if the code I wrote really does not has some memory leak or if lost memory is freed at each thread execution end, but if you are afraid as I was, I can say that using same structure and calls does not cause any real problem.
You do actually free up some of the memory you use, with the line of code:
~MyAddOn() { delete datas; }
In essence, C++ memory management boils down to always calling delete for every object created by new. There are also many additional architecture-specific and legacy 'C' memory management functions, but it is not strictly necessary to use these when you do not require the performance benefits.
As an example of what could potentially be a memory leak: You're passing the object held in the *callback pointer to the function AsyncQueueWorker. Yet nowhere in your code is this pointer freed, so unless the Queue worker frees it for you, there is a memory leak here.
You can use a memory tool such as valgrind to test your program further. It will spot most memory problems for you and comes highly recommended.
One thing I've observed is that you often ask (paraphrased):
Is it okay to declare X outside my loop?
To which the answer actually is that declaring variables inside of your loops is better, whenever you can do it. Declare variables as deep inside as you can, unless you have to re-use them. Variables are restricted in scope to the outermost set of {} brackets. You can read more about this in this question.
is it ok to use same x1K and x2K instances for all objects?
In essence, when you do this, if one of these objects modifies its 'x1K' string, then it will change for all of them. The advantage is that you free up memory. If the string is the same for all these objects anyway, instead of having to store say 1,000,000 copies of it, your computer will only keep a single one in memory and have 1,000,000 pointers to it instead. If the string is 9 ASCII characters long or longer under amd64, then that amounts to significant memory savings.
By the way, if you don't intend to modify a variable after its declaration, you can declare it as const, a keyword short for constant which forces the compiler to check that your variable is not modified after declaration. You may have to deal with quite a few compiler errors about functions accepting only non-const versions of things they don't modify, some of which may not be your own code, in which case you're out of luck. Being as conservative as possible with non-const variables can help spot problems.
Basically, I am looking for something more or less equivalent to the following C code:
int theGlobalCount = 0;
int
theGlobalCount_get() { return theGlobalCount; }
void
theGlobalCount_set(int n) { theGlobalCount = n; return; }
You could use a neat trick: declare a mutable global variable, and make a ref (aka mutable reference) point to it (no GC is required to make this work!). Then, implement functions to provide access to the mutable reference.
local
var theGlobalCount_var : int = 0
val theGlobalCount = ref_make_viewptr (view# theGlobalCount_var | addr# theGlobalCount_var)
in // in of [local]
fun
theGlobalCount_get () : int = ref_get_elt (theGlobalCount)
fun
theGlobalCount_set (n: int): void = ref_set_elt (theGlobalCount, n)
end // end of [local]
Note that declarations inside local-in are visible only to code inside in-end. Therefore, neither theGlobalCount_var nor theGlobalCount are visible outside the scope of the local.
Full code: glot.io
You can also use the extvar feature to update an external global variable (declared in the target language). This is very useful if you compile ATS to a language that does not support explicit pointers (e.g., JavaScript). Here is a running example that makes use of this feature:
http://www.ats-lang.org/SERVER/MYCODE/Patsoptaas_serve.php?mycode_url=http://pastebin.com/raw/MsXhVE0A
In the code below I show union-like class S which contains two non-related structs B and C. I show how to instantiate the non-POD std::string and delete it again and then switch S to S::CC and set the num int.
#include <vector>
#include <string>
#include <iostream>
#include <memory>
struct B
{
B() {}
~B() {}
std::string str;
void Func1() {}
};
struct C
{
C() {}
~C() {}
int num;
void Func2() {}
};
struct S
{
S() { tag = CC; }
S( const S& s )
{
switch( s.tag )
{
case BB:
new ( &b.str ) std::string;
b.str = s.b.str;
break;
case CC:
c.num = s.c.num;
default:
break;
}
}
~S()
{
switch( tag )
{
case BB:
b.str.~basic_string< char >();
break;
case CC:
c.num = 0;
break;
default:
break;
}
}
enum { BB, CC } tag;
union
{
B b;
C c;
};
};
struct H
{
H( std::initializer_list< S > initializerList ) : initListVect( initializerList ) {}
std::vector< S > initListVect;
};
int main()
{
S s;
s.tag = S::BB;
new ( &s.b.str ) std::string; // docs say use new placement to create memory
s.b.str = "bbb";
s.b.str.~basic_string< char >(); // string usage in B ok
s.tag = S::CC;
s.c.num = 333; // int usage in C ok
H h { }; // what should the init list be if I wanted 3 list elements S::BB, S::CC, S::BB?
return 0;
}
My goal, however, is to use S in an std::initializer_list. I don’t know what the format should be for initializeing h. What should the arguments be if I wanted to initialize h with these S::BB, S::CC, S::BB?
My compiler is VS2015.
Edit:
This post’s history: my posting comes from a need for a definitive answer to the question of storing compile-time-deduceable heterogeneous objects in an std::initializer_list. This question has been asked many times before and there have been many attempts at answers (see Heterogeneous containers in C++). The most simplistic answer is to use polymorphism, but this ignores the power of being able to define a type at compile time (templates). Besides, heterogeneous, non-related objects grouped together polymorphically means a lot of derived data members are useless, which sows usage and maintenance confusion downstream. Other advice given was to use boost::any or boost::variant, but this has the same weakness as polymorphism and reduces message declaration clarity. Another attempt at container object heterogeneity was the use of std::tuple, but although an initializer_list can certainly contain tuples, this approach too ignores compile-time type resolution. I even found a paper written in 1999 called Heterogeneous, Nested STL Containers in C++ which uses template template arguments to solve the heterogeneity problem. After all this, I settled on class-like unions which led to my posting here. Class-like unions for non-related/heterogeneous container objects has perfect message declaration clarity, no object size ambiguity, and is compile time template-able, and it leads to excellent downstream maintenance scenarios.
Edit2: (5 weeks later) Here is what has happened. 1) I implemented a full class-like union solution given the advice in this posting. The result was tedious and unwieldy with ‘tag’ being used to identify which sub-method to call for each new functionality. Low grade regarding code maintenance. 2) c++17 has accepted std::variant. Since that is currently not yet implemented in VS2015 Update 2, I set about using boost::variant. See What is the right c++ variant syntax for calling a member function set to a particular variant? which uses the Visitor pattern to allow access to initialized variant members and member functions. This eliminates the ‘tag’ switches and variant ‘get’ calls. Bottom line: I dropped my class-like union and adopted variant for creating maintainable code that uses initializer_list to store variant member functionality all being initializable at compile time (read: highly maintainable).
Alright, I'm feeling generous and I've made custom unions myself so he're some stuff that'll get you set up. I've rewritten your S structure to be more compliant and usable. (I've made changes marked by comments)
struct S
{
S() : tag(CC) // initializer
{
new (&c) C; // make C object
}
S(int num) : tag(CC) // added integer constructor
{
new (&c) C;
c.num = num;
}
S(const std::string& str) : tag(BB) // added string constructor
{
new (&b) B;
b.str = str;
}
S( const S& s ) : tag(s.tag)
{
if (tag == CC)
{
new (&c) C; // construct c
c.num = s.c.num;
}
else if (tag == BB)
{
new (&b) B; // construct b, not b.str
b.str = s.b.str;
}
}
S& operator= (const S& s) // added assignment operator
{
if (tag == s.tag) // just copy b or c
{
if (tag == CC)
c = s.c;
else
b = s.b;
}
else // reconstruct b or c
{
if (tag == CC)
{
c.~C(); // destroy c
new (&b) B; // construct b
b.str = s.b.str;
}
else
{
b.~B(); // destroy b
new (&c) C; // construct c
c.num = s.c.num;
}
tag = s.tag;
}
return *this;
}
~S()
{
if (tag == CC)
{
c.~C(); // destroy c
}
else if (tag == BB)
{
b.~B(); // destroy b, not b.str
}
}
enum { BB, CC } tag;
union
{
B b;
C c;
};
};
One of the things that you were doing improperly was skipping the construction and destruction of B and C and going straight for the internal variables. You should always create and destroy types properly even when they may be trivial. While this may work out, not initializing these objects properly is only asking for trouble (It also makes it easier should you change B or C in the future).
To make using the class easier, I added in the proper constructors for std::string and int as well as an assignment operator. Because now that we can construct the objects how we want, your main() could look like this:
int main()
{
S s; // default S
s = std::string("bbb"); // set to string
s = 333; // set to number
// use initialization list
H h { std::string("bb"), 33, std::string("bb") };
return 0;
}
I encourage you to modify B and C to use constructors to build their internals rather than relying on S.