How to create/destroy objects in "modern" C++? - c#

I am porting C# app into C++ linux app. I am confused with construction and destruction in "modern" (C++11 ?). I always thought you have to use new/delete but now it appears C++ recommendation is not to do so (is this correct or I read a wrong blog?).
What I have roughly (there are 6 subclasses of B and BRec atm):
class ARec : public BRec
class A : public B
. . .
class Factory
BRec GetRecord(WrapperStruct s)
{
if(s.Type == 'A')
{
A* a = (A*)s.Data;
auto rec = ARec((ushort)a->Num);
rec.OtherField = a.OtherField;
return rec;
}
. . .
main
// separate pthread
void* Logger(void* arg) {
int* thread_state = (int*)arg;
auto f = Factory();
WrapperStruct item;
while (true)
{
q->try_dequeue(item);
auto rec = f.GetRecord(item);
auto bytes = f.GetBytes(rec);
// write bytes to file ...
delete bytes;
if(*thread_state == -1)
pthread_exit(0);
}
Question - how does compiler would know when to delete s.Data in factory method? Same - rec if it was created in a class method and then crossed to other method (while in Logger)? Is there a simple guide how to manage variables' memory in C++11 ?
EDIT: s.Data contains ref to an object created in a 3rd party dll and can be of different types hence the s.Type field

Smart pointers are the key.
std::shared_ptr<Foo> foo = std::make_shared<Foo>();
std::unique_ptr<Foo> bar = std::make_unique<Foo>();
Shared pointers can be copied. They do reference counting. When the reference count drops to zero, they'll delete their contents automatically.
Unique pointers can't be copied. They can be copied by reference. When the unique pointer goes out of reference, it frees the object for you.
So it works a lot like Java now.
void notAMemoryLeak() {
std::shared_ptr<Foo> foo = std::make_shared<Foo>();
}
Other than that, you treat them like pointers. The syntax for their use at this point is identical, except you're passing smart pointers, not Foo *.
void myFunct(std::unique_ptr<Foo> &foo) {
cout << "Foo: " << foo->getName() << "\n";
}
The make_shared and make_unique can take the same arguments as any of your Foo's constructors, so feel free to pass stuff.
I do one more thing:
class Foo {
public:
typedef std::shared_ptr<Foo> Pointer;
...
};
Foo::Pointer foo = std::make_shared<Foo>();
Sometimes I also create static methods to make it even cleaner. This is stylistic and not necessary. Some people might fault me. But it's clean and easy to read.

Related

For C# binary, where's the anonymous class's type information stored?

I did an experiment in C#, first I created a class library called "ClassLibrary1", with code below:
public class ClassLibrary1
{
public static void f()
{
var m = new { m_s = "abc", m_l = 2L };
Console.WriteLine(m.GetType());
}
}
Note, I removed namespace information generated by IDE.
Then I created console application with code below:(also removed namespace)
while referring to ClassLibrary1:
class Program
{
static void Main()
{
var m = new {m_s = "xyz", m_l = 5L};
Console.WriteLine(m.GetType());
ClassLibrary1.f();
}
}
I run the program, it prints:
<>f__AnonymousType0`2[System.String,System.Int64]
<>f__AnonymousType0`2[System.String,System.Int64]
Press any key to continue . . .
The output indicates that the 2 anonymous classes defined in class library and console application are having identical class type.
My question is: how does C# binary store its type information for all the classes it contains? If it's stored in a global place, when the exe is built with dll reference, 2 same anonymous type information is there, so
(1) Is name duplication an error that should be avoid?
(2) If not an error like I tested, how could C# binary store duplicate type information?
(3) And in runtime, what's the rule to look up type information to create real objects?
Seems a bit confusing in my example.
Thanks.
I removed namespace information
Irrelevant. Anonymous types for an assembly are generated in the same namespace, namely an empty one.
Furthermore, see C# specs 7.6.10.6 Anonymous object creation expressions:
Within the same program, two anonymous object initializers that specify a sequence of properties of the same names and compile-time types in the same order will produce instances of the same anonymous type.
Confusingly, "program" here means "assembly". So:
how does C# binary store its type information for all the classes it contains? If it's stored in a global place, when the exe is built with dll reference, 2 same anonymous type information is there
That's right, but the types are unique per assembly. They can have the same type name, because they're in a different assembly. You can see that by printing m.GetType().AssemblyQualifiedName, which will include the assembly name.
It is possible to have duplicate names in the .NET assembly, because metadata items (classes, fields, properties etc) are referenced internally by numeric metadata token, not by the name
Although the use of duplicate names is restricted in ECMA-335 (except several special cases), this possibility is exploited by a number of obfuscators, and, probably, by the compilers in cases when the name of the metadata item (class in your case) is not directly exposed to the user code
EDIT: CodeCaster is right with his answer, the names reside in different assemblies in your case, hence the duplicate names. Though I believe my point with having duplicate names in the same assembly is valid, but may not be applicable to this particular question.
(Note, I'm using the reversed prime ‵ character here where the grave accent character is in the code, since that has a special meaning in markdown, and they look similar. This may not work on all browsers).
My question is: how does C# binary store its type information for all the classes it contains?
The same way it stores any other class. There is no such thing as an anonymous type in .NET, it's something that the C# (and other .NET languages) provide by compiling to what at the CIL level is a perfectly normal class with a perfectly normal name; because at the CIL level there's nothing special about the name <>f__AnonymousType‵2[System.String,System.Int64] though its being an illegal name in C#, VB.NET and many other languages has the advantage of avoiding direct use that would be inappropriate.
If it's stored in a global place, when the exe is built with dll reference, 2 same anonymous type information is there.
Try changing your Console.WriteLine(m.GetType()) to Console.WriteLine(m.GetType().AssemblyQualifiedName) and you'll see that they aren't the same type.
Is name duplication an error that should be avoid?
No, because CIL produced uses the AssemblyQualifiedName if it deals with classes from other assemblies.
If not an error like I tested, how could C# binary store duplicate type information?
The error was not in what you looked at, but in how you looked at it. There is no duplication.
And in runtime, what's the rule to look up type information to create real objects?
The type gets compiled directly into the calls, with the lookup happening at that point. Consider your f():
public static void f()
{
var m = new { m_s = "abc", m_l = 2L };
Console.WriteLine(m.GetType());
}
That is compiled to two things. The first is the anonymous type here goes into a list of definitions of anonymous types in the assembly, and they are all compiled into the equivalent of:
internal class SomeImpossibleName<M_SType, M_LType>
{
private readonly M_SType _m_s;
private readonly M_LType _m_l;
public SomeImpossibleName(M_SType s, M_LType l)
{
_m_s = s;
_m_l = l;
}
public M_SType m_s
{
get { return _m_s; }
}
public M_LType m_l
{
get { return _m_l; }
}
public override bool Equals(object value)
{
var compareWith = value as SomeImpossibleName<M_SType, M_LType>;
if(compareWith == null)
return false;
if(!EqualityComparer<M_SType>.Default.Equals(_m_s, compareWith._m_s))
return false;
return EqualityComparer<M_LType>.Default.Equals(_m_l, compareWith._m_l);
}
public override int GetHashCode()
{
unchecked
{
return (-143687205 * -1521134295 + EqualityComparer<M_SType>.Default.GetHashCode(_m_s))
* 1521134295 + EqualityComparer<M_LType>.Default.GetHashCode(_m_l);
}
}
public override string ToString()
{
return new StringBuilder().Append("{ m_s = ")
.Append((object)_m_s)
.Append(", m_l = ")
.Append((object)_m_l)
.Append(" }")
.ToString();
}
}
Some things to note here:
This uses a generic type, to save on the compiled size if you had a bunch of different classes with an m_s followed by an m_l of different types.
This allows for a simple but reasonable comparison between objects of the same type, without which GroupBy and Distinct would not work.
I called this SomeImpossibleName<M_SType, M_LType> the real name would be <>f__AnonymousType0<<m_s>j__TPar, <m_l>j__TPar>>. That is, not only is the main part of the name impossible in C#, but so are the names of the type parameters.
If you have two methods that each do new Something{ m_s = "abc", m_l = 2L } they will both use this type.
The constructor is optimised. While in C# generally calling var x = new Something{ m_s = "abc", m_l = 2L } is the same as calling var x = new Something; x.m_s = "abc"; x.m_l = 2L; the code created for doing so with an anonymous type is actually the equivalent to var x = new Something("abc", 2L). This both gives a performance benefit but more importantly allows anonymous types to be immutable even though the form of constructor used only works with named types if they are mutable.
Also the following CIL for the method:
.method public hidebysig static void f () cil managed
{
.maxstack 2
.locals init
(
[0] class '<>f__AnonymousType0`2'<string, int64>
)
// Push the string "abc" onto the stack.
ldstr "abc"
// Push the number 2 onto the stack as an int32
ldc.i4.2
// Pop the top value from the stack, convert it to an int64 and push that onto the stack.
conv.i8
// Allocate a new object can call the <>f__AnonymousType0`2'<string, int64> constructor.
// (This call will make use of the string and long because that's how the constructor is defined
newobj instance void class '<>f__AnonymousType0`2'<string, int64>::.ctor(!0, !1)
// Store the object in the locals array, and then take it out again.
// (Yes, this is a waste of time, but it often isn't and so the compiler sometimes adds in these
// stores).
stloc.0
ldloc.0
// Call GetType() which will pop the current value off the stack (the object) and push on
// The result of GetType()
callvirt instance class [mscorlib]System.Type [mscorlib]System.Object::GetType()
// Call WriteLine, which is a static method, so it doesn't need a System.Console item
// on the stack, but which takes an object parameter from the stack.
call void [mscorlib]System.Console::WriteLine(object)
// Return
ret
}
Now, some things to note here. Notice how all the calls to methods defined in the mscorlib assembly. All calls across assemblies use this. So too do all uses of classes across assemblies. As such if two assemblies both have a <>f__AnonymousType0‵2 class, they will not cause a collision: Internal calls would use <>f__AnonymousType0‵2 and calls to the other assembly would use [Some.Assembly.Name]<>f__AnonymousType0‵2 so there is no collision.
The other thing to note is the newobj instance void class '<>f__AnonymousType0‵2'<string, int64>::.ctor(!0, !1) which is the answer to your question, "And in runtime, what's the rule to look up type information to create real objects?". It isn't looked up at runtime at all, but the call to the relevant constructor is determined at compile time.
Conversely, there's nothing to stop you from having non-anonymous types with the exact same name in different assemblies. Add an explicit reference to mscorlib to a console application project and change its alias from the default global to global, mscrolib and then try this:
namespace System.Collections.Generic
{
extern alias mscorlib;
public class List<T>
{
public string Count
{
get{ return "This is a very strange “Count”, isn’t it?"; }
}
}
class Program
{
public static void Main(string[] args)
{
var myList = new System.Collections.Generic.List<int>();
var theirList = new mscorlib::System.Collections.Generic.List<int>();
Console.WriteLine(myList.Count);
Console.WriteLine(theirList.Count);
Console.Read();
}
}
}
While there's a collision on the name System.Collections.Generic.List, the use of extern alias allows us to specify which assembly the compiler should look in for it, so we can use both versions side by side. Of course we wouldn't want to do this and its a lot of hassle and confusion, but compilers don't get hassled or confused in the same way.

String inside structure behavior

Let's say we have structure
struct MyStruct
{
public string a;
}
When we assign it to the new variable what will be happened with the string? So for example, we expect that string should be shared when structs are copied in the stack. We're using this code to test it, but it returns different pointers:
var a = new MyStruct();
a.a = "test";
var b = a;
IntPtr pA = Marshal.StringToCoTaskMemAnsi(a.a);
IntPtr pB = Marshal.StringToCoTaskMemAnsi(b.a);
Console.WriteLine("Pointer of a : {0}", (int)pA);
Console.WriteLine("Pointer of b : {0}", (int)pB);
The question is when structs are copied in the stack and have string inside did it share the string or the string is recreated?
[UPDATE]
We also tried this code, it returns different pointers as well:
char charA2 = a.a[0];
char charB2 = b.a[0];
unsafe
{
var pointerA2 = &charA2;
var pointerB2 = &charB2;
Console.WriteLine("POinter of a : {0}", (int)pointerA2);
Console.WriteLine("Pointer of b : {0}", (int)pointerB2);
}
The code you use to test it 'Copies the contents of a managed String to a block of memory allocated from the unmanaged COM task allocator.' according to MSDN. I would be surprised if any two subsequent calls to StringToCoTaskMemAnsi would return the same pointer. You can look at the memory address of the two string references or assign an object id using the debugger. Or easier: object.ReferenceEquals(a.a, b.a);
In your update, you are pointing to the stack location of the character variables, also not a good way of finding out. In any case, you are just copying the reference when you assign a string to another string, so they should always be the same.
Strings are immutable in storage and a reference type. Furthermore in your example, the string "test" is interned. So no matter how many copies of the struct you makes you ultimately have multiple pointers to the same underling storage (unless you go through gyrations to copy it to a new block of memory which your contrived examples are doing)
Rest assured that there is only one copy, pointed at multiple times.

Cycle in the struct layout that doesn't exist

This is a simplified version of some of my code:
public struct info
{
public float a, b;
public info? c;
public info(float a, float b, info? c = null)
{
this.a = a;
this.b = b;
this.c = c;
}
}
The problem is the error Struct member 'info' causes a cycle in the struct layout. I'm after struct like value type behaviour. I could simulate this using a class and a clone member function, but I don't see why I should need to.
How is this error true? Recursion could perhaps cause construction forever in some similar situations, but I can't think of any way that it could in this case. Below are examples that ought to be fine if the program would compile.
new info(1, 2);
new info(1, 2, null);
new info(1, 2, new info(3, 4));
edit:
The solution I used was to make "info" a class instead of a struct and giving it a member function to returned a copy that I used when passing it. In effect simulating the same behaviour as a struct but with a class.
I also created the following question while looking for an answer.
Value type class definition in C#?
It's not legal to have a struct that contains itself as a member. This is because a struct has fixed size, and it must be at least as large as the sum of the sizes of each of its members. Your type would have to have 8 bytes for the two floats, at least one byte to show whether or not info is null, plus the size of another info. This gives the following inequality:
size of info >= 4 + 4 + 1 + size of info
This is obviously impossible as it would require your type to be infinitely large.
You have to use a reference type (i.e. class). You can make your class immutable and override Equals and GetHashCode to give value-like behaviour, similar to the String class.
The reason why this creates a cycle is that Nullable<T> is itself a struct. Because it refers back to info you have a cycle in the layout (info has a field of Nullable<info> and it has a field of info) . It's essentially equivalent to the following
public struct MyNullable<T> {
public T value;
public bool hasValue;
}
struct info {
public float a, b;
public MyNullable<info> next;
}
The real problem is on this line:
public info? c;
Since this is a struct, C# needs to know the inner info/s layout before it could produce outer info's layout. And the inner info includes an inner inner info, which in turn includes an inner inner inner info, and so on. The compiler cannot produce a layout because of this circular reference issue.
Note: info? c is a shorthand for Nullable<info> which is itself a struct.
There isn't any way to achieve mutable value semantics of variable-sized items (semantically, I think what you're after is to have MyInfo1 = MyInfo2 generate a new linked list which is detached from the one started by MyInfo2). One could replace the info? with an info[] (which would always either be null or else populated with a single-element array), or with a holder class that wraps an instance of info, but the semantics would probably not be what you're after. Following MyInfo1 = MyInfo2, changes to MyInfo1.a would not affect MyInfo2.a, nor would changes to MyInfo1.c affect MyInfo2.c, but changes to MyInfo1.c[0].a would affect MyInfo2.c[0].a.
It would be nice if a future version of .net could have some concept of "value references", so that copying a struct wouldn't simply copy all of its fields. There is some value to the fact that .net does not support all the intricacies of C++ copy constructors, but there would also be value in allowing storage locations of type 'struct' to have an identity which would be associated with the storage location rather than its content.
Given that .net does not presently support any such concept, however, if you want info to be mutable, you're going to have to either put up with mutable reference semantics (including protective cloning) or with weird and wacky struct-class-hybrid semantics. One suggestion I would have if performance is a concern would be to have an abstract InfoBase class with descendants MutableInfo and ImmutableInfo, and with the following members:
AsNewFullyMutable -- Public instance -- Returns a new MutableInfo object, with data copied from the original, calling AsNewFullyMutable on any nested references.
AsNewMutable -- Public instance -- Returns a new MutableInfo object, with data copied from the original, calling AsImmutable on any nested references.
AsNewImmutable -- Protected instance -- Returns a new ImmutableInfo object, with data copied from the orignal, calling AsImmutable (not AsNewImmutable) on any nested references.
AsImmutable -- Public virtual -- For an ImmutableInfo, return itself; for a MutableInfo, call AsNewImmutable on itself.
AsMutable -- Public virtual -- For a MutableInfo, return itself; for an ImmutableInfo, call AsNewMutable on itself.
When cloning an object, depending upon whether one expected that the object or its descendants would be cloned again before it had to be mutated, one would call either AsImmutable, AsNewFullyMutable, or AsNewMutable. In scenarios where one would expect an object to be repeatedly defensively cloned, the object would be replaced by an immutable instance which would then no longer have to be cloned until there was a desire to mutate it.
Disclaimer: This may not achieve the goal of "struct like value type behaviour."
One solution is to use an array of one item to essentially get a reference the recursively referenced structure. Adapting my approach to your code looks something like this.
public struct info
{
public float a, b;
public info? c
{
get
{
return cArray[nextIndex];
}
set
{
steps[nextIndex] = value;
}
}
private info?[] cArray;
public info(float a, float b, info? c = null)
{
this.a = a;
this.b = b;
this.cArray = new info?[] { c }
this.c = c;
}
}

how to find allocated memory by a variable?

class app {
public int x = 3;
static void Main(string[] args)
{
}
}
it's possible get the memory address allocated by x variable?
the example can be in C, C++, C# or D.
I hope it is clear
Thanks in advance
The ampersand (&) is the "address-of" operator in most C-like languages:
int x;
printf("Address of x is %p\n", &x);
The return value of & is effectively a pointer to its operand.
In C and in C++ this is fairly straight-forward. I'll give the example in C++:
struct App
{
int x;
App() : x(3) { }
};
int main()
{
App a;
int * p = &a.x; // address goes here
}
There is of course no such thing as "the variable App::x", since App is only the type. Each instance of this type, such as a in the example, carries its own set of member variables, and a pointer to the member variable is readily obtained. (The same is true for plain data structs in C.)
Note that C++ has another, related feature: Member pointers. This allows us to form the opaque value int App::*pm = &App::x which by itself doesn't point to anything, but only carries information about the offset of App::x inside the class, if you will. This animal can be used together with an instance to obtain the actual value, e.g. a.*pm.
Skipping D and E. C# and F# (and other CLR languages) - there is no fixed addres for any partcular variable in general. One can use managed debugger (i.e. WinDbg + SOS) to find address of any particular variable, or use fixed along with interop classes.

Is it possible to step through the members of a C++ struct?

I want to step through the members of a C++ struct and print out their values. I can easily code this explicitly, but is there any way of doing it without actually knowing what's in the struct?
I suppose I'm looking for a C++ equivalent of C#'s foreach command.
Thanks for any help.
ADD: I'm doing something like this in C#. This code sets the struct members from an XML file read previously:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
private struct SettingsStruct
{
public uint nLength;
}
private void UpdateSettings()
{
SettingsStruct settings = new SettingsStruct();
foreach (FieldInfo fieldInfo in typeof(SettingsStruct).GetFields())
{
string settingName = "SETTING." + fieldInfo.Name.ToUpper();
if (appSettings.Contains(settingName))
{
switch (fieldInfo.FieldType.FullName)
{
case "System.UInt32":
fieldInfo.SetValueDirect(__makeref(settings), uint.Parse((string)appSettings[settingName]));
break;
}
}
}
}
If you are willing to use boost fusion you can do this. First "promote" this structure to a fusion sequence, and then you can iterate through the sequence printing out each member.
You could overload operator<< for your struct, then you only have to write the code once.
The following Stackoverflow answer should give you an idea on what you are looking for
Iterate Over Struct; Easily Display Struct Fields And Values In a RichEdit Box
Afraid not. C++ offers limited reflective capability. The RTTI C++ system gives you access to types, but no introspection to the fields within that type.
With some macro wizardry / hackery you might be able to achieve this, see Reflection for C++ for an example.
The foreach command does'nt do what you are saying in C#. The foreach iterates over the elements of a collection (array, set, list ...) not the members of a struct (say "length" ...).
The equivalent of foreach in C++ is to use iterators (xs.begin(), xs.end()). You can use BOOST_FOREACH to have a cleaner syntax (or for(X& s : xs) in C++1x).
C++ doesn't allow iteration over general class members. However, if you are prepared to accept some limitations, and use techniques that some will regard as pure evil, you can set up a framework to allow iteration over members of a particular family of class types. This works by abusing the fact that the default assignment operator is recursively applied to all members of a class.
First we need to declare the types to include in the iteration:
struct Visitable1;
struct Visitable2;
struct Visitable3;
We also need an abstract base class for operations to do while iterating (destructor omitted for brevity; for safety, it should be either virtual or protected):
struct Visitor
{
virtual void visit(Visitable1 &) = 0;
virtual void visit(Visitable2 &) = 0;
virtual void visit(Visitable3 &) = 0;
static Visitor * current;
};
and a base class (using the "curiously recursive template" idiom) for the types we can include in the iteration; this is where the operator abuse happens, modifying the behaviour of self-assignment:
template <typename T>
struct Visitable
{
void operator=(Visitable const & other)
{
if (&other == this) {
Visitor::current->visit(static_cast<T&>(*this));
}
}
};
struct Visitable1 : Visitable<Visitable1> { /* some stuff */ };
struct Visitable2 : Visitable<Visitable2> { /* some stuff */ };
struct Visitable3 : Visitable<Visitable3> { /* some stuff */ };
Finally, we can define the iteration itself:
template <class T, class Visitor>
void for_each(T & t, Visitor v)
{
Visitor::current = &v;
t = t;
}
This does have some notable shortcomings:
The "visit" functions are virtual, and so can't be generic. I can't currently think of a way to allow the use of different Visitor classes without an abstract base class. As a consequence, the iteration can only be applied to a predeclared set of types.
The use of a static variable (Visitor::current) means that only one iteration can be in progress at any time, giving thread-safety and reentrancy issues. I can't currently think of a better way to pass state to operator=, since this only works when overloading the default operator=, with a single argument of the same type as the assignee.
You may be lynched if anyone catches you writing code like this.
See codepad.org for a demonstration.

Categories

Resources