Array memory allocation in C# - c#

I was wandering which way of doing below code is better :
a)
byte[] tmp = BitConverter.GetBytes(Number)
b)
byte[] tmp = new byte[sizeof(Number)]
tmp = BitConverter.GetBytes(Number)
Is it necessary to use dynamic memory allocation ?

Definitely a).
b) creates two arrays, the first of which is completely unnecessary and is thrown away right after being initialized.

Actually second one is redundant, because GetBytes returns a new array so you are throwing away the first array you created...

The first is better for two reasons:
It is more readable
In sample b the first allocation is thrown away as tmp is re-assigned to the return value of GetBytes

Related

C# : Changing copy of array changes array itself

I have a very basic question in C#. So I have an array of int called m_permutation (property of a class), and in a method of the class I have the following code:
int[] newPermutation = new int[m_permutation.Length];
newPermutation = m_permutation;
newPermutation[0] = 5;
I am confused as to why m_permutation is also changed in this code, and how can I fix it ?
I understand that I can initialize newPermutation via a loop for, to get the same values of m_permutation, and that fixes it. However, can somebody explain why this happens, and what is the best fix ?
Thank you,
Bogdan
There's some good, and some bad, about your expectations for your code.
Let's go through what your code is actually doing:
int[] newPermutation = new int[m_permutation.Length];
This will declare a new variable, newPermutation, to be an array of ints, and then construct a new int array containing m_permutation.Length elements.
So far so good.
The next line, not so much:
newPermutation = m_permutation;
This line will actually replace the reference in your array variable newPermutation to, after the assignment, refer to the same array as m_permutation.
Let's consider what an array variable actually is.
When you do this:
int[] x = new int[5];
Then you're doing a couple of things:
You're declaring a variable, x
You're constructing a new object containing the int array
You're assigning the variable, x to refer to this object
After the 2nd line:
newPermutation = m_permutation;
you're essentially saying this:
OK, you know that array we just constructed? Forget that
Let's now refer to this other array, the one that the variable m_permutation is also referring to.
So when this line executes:
newPermutation[0] = 5;
You're essentially saying: The array that newPermutation is now referring to, its first element should now have the value 5.
Since newPermutation at this point refers to the same array as m_permutation, it appears that you're modifying an additional array but in reality you only have one array. You do, however, have two variables referring to the same array.
I recommend you read my answer here regarding pointers since this is relevant.
However, there is an easy fix to your problem.
You can ask for a copy of the array, instead of a reference to the original one.
Simply change your code to this:
int[] newPermutation = m_permutation.ToArray();
The .ToArray() method is guaranteed to return a new array, so this won't be shared with the original.
Bear in mind, however, that if you do this with anything more complex than an int, such as an object, you're only getting copies of the object references, not the objects themselves. You can get back to Stack Overflow with new questions when/if you get to this point.
Because they both reference the same object in memory.
You can use,
Array.Copy(m_permutation, newPermutation,m_permutation.Length );

Assign this keyword in C#

Main question is what are the implications of allowing the this keyword to be modified in regards to usefulness and memory; and why is this allowed in the C# language specifications?
The other questions/subparts can be answered or not if choose to do so. I thought answers to them would help clarify the answer to the main question.
I ran across this as an answer to What's the strangest corner case you've seen in C# or .NET?
public struct Teaser
{
public void Foo()
{
this = new Teaser();
}
}
I've been trying to wrap my head around why the C# language specifications would even allow this. Sub-part 1. is there anything that would justify having this be modifiable? Is it every useful?
One of the comments to that answer was
From CLR via C#: The reason they made this is because you
can call the parameterless constructor of a struct in another
constructor. If you only want to initialize one value of a struct and
want the other values to be zero/null (default), you can write public
Foo(int bar){this = new Foo(); specialVar = bar;}. This is not
efficient and not really justified (specialVar is assigned twice), but
just FYI. (That's the reason given in the book, I don't know why we
shouldn't just do public Foo(int bar) : this())
Sub-part 2. I'm not sure I follow that reasoning. Can someone clarify what he meant? Maybe a concrete example of how it would be used?
EDIT (Disregard stack or heap main point is in regards to memory release or garbage collection. Instead of the int[] you could replace that with 262144 public int fields)
Also from my understanding structs are created on the stack as opposed to the heap if this struct were to have a 1 Mb byte array field initialized as so
public int[] Mb = new int[262144];
Sub-part 3. does this ever get removed from the stack when Foo is called? To me it seems since the struct never went out of scope it would not be removed from the stack. Don't have time tonight to create a test case but maybe I will for this one tomorrow.
In the below code
Teaser t1 = new Teaser();
Teaser tPlaceHolder = t1;
t1.Foo();
Sub-part 4. Are t1 and tPlaceHolder occupying the same or different address space?
Sorry to bring up a 3 year old post but this one has really got my head scratching.
FYI first question on stackoverflow so if I got something wrong with the question kindly post a comment and I will edit.
After 2 days I'll put a bounty of 50 on this question even if I have a winner chosen in my mind already as I think the answer will require a reasonable amount of work to explain the questions.
First of all, I think you should start by examining if you're even asking the right question. Perhaps we should be asking, "Why would C# not allow assignment to this in a struct?"
Assigning to the this keyword in a reference type is potentially dangerous: you are overwriting a reference to the object who's method you are running; you could even be doing so within the constructor that is initializing that reference. Its not clear what the behavior of that ought to be. To avoid having to figure that out, since it is not generally useful, it's not allowed by the spec (or compiler).
Assigning to the this keyword in a value type, however, is well defined. Assignment of value types is a copy operation. The value of each field is recursively copied over from right to left side of the assignment. This is a perfectly safe operation on a structure, even in a constructor, because the original copy of the structure is still present, you are just changing its data. It is exactly equivalent to manually setting each field in the struct. Why should the spec or compiler forbid an operation that is well-defined and safe?
This, by the way, answers one of your sub-questions. Value type assignment is a deep copy operation, not a reference copy. Given this code:
Teaser t1 = new Teaser();
Teaser tPlaceHolder = t1;
t1.Foo();
You have allocated two copies of your Teaser structure, and copied the values of the fields in the first into the fields in the second. This is the nature of value types: two types that have identical fields are identical, just like two int variables that both contain 10 are identical, regardless of where they are "in memory".
Also, this is important and worth repeating: careful making assumptions about what goes on "the stack" vs "the heap". Value types end up on the heap all the time, depending on the context in which they are used. Short-lived (locally scoped) structs that are not closed over or otherwise lifted out of their scope are quite likely to get allocated onto the stack. But that is an unimportant implementation detail that you should neither care about nor rely on. The key is that they are value types, and behave as such.
As far as how useful assignment to this really is: not very. Specific use cases have been mentioned already. You can use it to mostly-initialize a structure with default values but specify a small number. Since you are required to set all fields before your constructor returns, this can save a lot of redundant code:
public struct Foo
{
// Fields etc here.
public Foo(int a)
{
this = new Foo();
this.a = a;
}
}
It can also be used to perform a quick swap operation:
public void SwapValues(MyStruct other)
{
var temp = other;
other = this;
this = temp;
}
Beyond that, its just an interesting side-effect of the language and the way that structures and value types are implemented that you will most likely never need to know about.
Having this assignable allows for 'advanced' corner cases with structs. One example i found was a swap method:
struct Foo
{
void Swap(ref Foo other)
{
Foo temp = this;
this = other;
other = temp;
}
}
I would strongly argue against this use since it violates the default 'desired' nature of a struct which is immutability. The reason for having this option around is arguably unclear.
Now when it comes to structs themselfs. They differ from classes in a few ways:
They can live on the stack rather than the managed heap.
They can be marshaled back to unmanaged code.
They can not be assigned to a NULL value.
For a complete overview, see: http://www.jaggersoft.com/pubs/StructsVsClasses.htm
Relative to your question is whether your struct lives on the stack or the heap. This is determined by the allocation location of a struct. If the struct is a member of a class, it will be allocated on the heap. Else if a struct is allocated directly, it will be allocated on the heap (Actually this is only a part of the picture. This whole will get pretty complex once starting to talk about closures introduced in C# 2.0 but for now it's sufficient in order to answer your question).
An array in .NET is be default allocated on the heap (this behavior is not consistent when using unsafe code and the stackalloc keyword). Going back to the explanation above, that would indicate that the struct instances also gets allocated on the heap. In fact, an easy way of proving this is by allocating an array of 1 mb in size and observe how NO stackoverflow exception is thrown.
The lifetime for an instance on the stack is determined by it's scope. This is different from an instance on the manager heap which lifetime is determined by the garbage collector (and whether there are still references towards that instance). You can ensure that anything on the stack lives as long as it's within scope. Allocating an instance on the stack and calling a method wont deallocate that instance until that instance gets out of scope (by default when the method wherein that instance was declared ends).
A struct cant have managed references towards it (pointers are possible in unmanaged code). When working with structs on the stack in C#, you basically have a label towards an instance rather than a reference. Assigning one struct to another simply copies the underlying data. You can see references as structs. Naively put, a reference is nothing more than a struct containing a pointer to a certain part in memory. When assigning one reference to the other, the pointer data gets copied.
// declare 2 references to instances on the managed heap
var c1 = new MyClass();
var c2 = new MyClass();
// declare 2 labels to instances on the stack
var s1 = new MyStruct();
var s2 = new MyStruct();
c1 = c2; // copies the reference data which is the pointer internally, c1 and c2 both point to the same instance
s1 = s2; // copies the data which is the struct internally, c1 and c2 both point to their own instance with the same data
You can take advantage of this and mutate an immutable structure
public struct ImmutableData
{
private readonly int data;
private readonly string name;
public ImmutableData(int data, string name)
{
this.data = data;
this.name = name;
}
public int Data { get => data; }
public string Name { get => name; }
public void SetName(string newName)
{
// this wont work
// this.name = name;
// but this will
this = new ImmutableData(this.data, newName);
}
public override string ToString() => $"Data={data}, Name={name}";
}
class Program
{
static void Main(string[] args)
{
var X = new ImmutableData(100, "Jane");
X.SetName("Anne");
Debug.WriteLine(X);
// "Data=100, Name=Anne"
}
}
This is advantageous as you can implement IXmlSerializable and maintain the robustness of immutable structures, while allowing serialization (that happens one property at a time).
Just two methods in the above example to achieve this:
public void ReadXml(XmlReader reader)
{
var data = int.Parse(reader.GetAttribute("Data"));
var name = reader.GetAttribute("Name");
this = new ImmutableData(data, name);
}
public void WriteXml(XmlWriter writer)
{
writer.WriteAttributeString("Data", data.ToString());
writer.WriteAttributeString("Name", name);
}
which creates the followng xml file
<?xml version="1.0" encoding="utf-8"?>
<ImmutableData Data="100" Name="Anne" />
and can be read with
var xs = new XmlSerializer(typeof(ImmutableData));
var fs = File.OpenText("Store.xml");
var Y = (ImmutableData)xs.Deserialize(fs);
fs.Close();
I came across this when I was looking up how System.Guid was implemented, because I had a similar scenario.
Basically, it does this (simplified):
struct Guid
{
Guid(string value)
{
this = Parse(value);
}
}
Which I think is a pretty neat solution.

Are all objects Immutable inside Heap?

Given,
public class SomeClass {
public string SomeName{get;}
public List<string> RelatedNames{get;}
}
public class Program{
public void Main(){
var someClassInstance = new SomeClass(){ SomeName = "A", RelatedNames = new List<string>(1){ "a" }};
// So, now someClassInstance have been allocated some memory in heap = 1 string object and a list with 1 string object.
// Since SomeClass is mutable, it could be modified as below
someClassInstance.SomeName = "Now This is much more than a name";
someClassInstance.RelatedNames = someClassInstance.RelatedNames.AddRange(new List<string>(100} { "N","o","w".....});
//Now what happens inside heap?
//1.someClassInstance.SomeName will move it's pointer to another string inside heap
//2.someClassInstance.RealtedNames will move it's pointer to another List<>(101) inside heap.
//Is it correct? Then where is 'mutability' ?
}
}
As mentioned in the comments above, "AFAIK" on modifying a mutable object the internal pointers of that object will just point to another memory location inside heap. If that is correct, then does that mean that all objects inside heap (reference type) are immutable?
Thanks for your interest.
Where's mutability? Right there:
someClassInstance.SomeName = "Now This is much more than a name";
someClassInstance.RelatedNames = new List<string>(100} { "N","o","w".....};
You just mutated the object pointed to by someClassInstance.
Also, your example is a bit contrived. Strings are indeed immutable, but Lists are not, so you could have done this:
someClassInstance.RelatedNames.Add("HELLO!");
And then you just mutated the object pointed to by someClassInstance.RelatedNames.
EDIT: I see you changed your question. Well, then:
someClassInstance.SomeName will move it's pointer to another string inside heap
someClassInstance.RealtedNames will move it's pointer to another List<>(101) inside heap.
1 is true because String was designed to be immutable. That's why there's the StringBuilder class in case you need a mutable string.
2 is false, because that's not how List is implemented. Perhaps that's where your confusion comes from. Still, when you invoke AddRange, someClassInstance.RelatedNames will still point to the same instance, but that instance's internal state will have changed (most likely, its backing array will have been changed to point to a different array object, and its count would now be 101). In fact, a reference cannot magically change based on the operations that are invoked to the object it refers to.
And none of that changes the fact that someClassInstance's internal state was mutated anyway.
Object in the CLR are definitely not immutable by default. There is a little bit of confusion here because you've used string in your example which is a type that's implemented as an immutable type. This is certainly not the default in .Net though and mutability is far more common than immutability.
Take this line as an example
someClassInstance.SomeName = "Now This is much more than a name";
There are 3 objects of interest here in this statement.
The object referenced by someClassInstance.SomeName
The string which has the value "Now this is much more than a name"
The object referenced by 'someClassInstance`
All 3 of these values live in the heap. The execution of this statement will mutate the contents of the object referenced by someClassInstance. This is a prime example of mutability in action. If everything in this scenario were immutable then the settnig of SomeName would need to produce a copy of the object referenced by someClassInstance and give it the new value. This doesn't happen here and can be demonstrated by the following
var obj = someClassInstance; // Both reference the same object
someClassInstance.SomeName = "hello";
Console.WriteLine(someClassInstance.SomeName): // Prints "hello"
Yes because they are put on the heap using new or malloc and are pointers. As such you can only add or remove pointer references. So technically the objects themselves are not immutable, since they are not on the heap to begin with, but the pointer allocations on the heap are immutable.

Replace object but keep previous memory location in c#

Let's say I have a list:
List<object> list = new List();
list.Add(object1);
list.Add(object2);
object foo = list[0];
How do I make a call to list to replace list[0] such that foo will automatically point to the newly replaced object?
I know this line won't do the trick as foo will continue pointing to the old value of list[0]...
list[0] = object3;
Thanks!
It's not possible in my opinion. You need an additonal level of indirection which you have to implement yourself.
You could use a delegate/ anonymous lambda that fetches list[0]:
Func<object> foo = () => list[0];
Of course that changes the syntax slightly since it's now foo() instead of foo but it has the effect that you can fetch the value of list[0] at any time later and it always gets the current value.
What you really want to be able to do is to override the assignment operator but that's not possible in C#. The closest you'll get is to create a class that behaves a bit like Nullable<T> having a .Value property on it and assign to that .Value property instead of overwriting the object itself in the list.
You can use the fixed keyword but only in unsafe code. But i'm not sure what your attempting to do so it may not suite your needs if you need this level of control c++ cli would be a better choice.
Unsafe pointers are one possibility: http://msdn.microsoft.com/en-us/library/y31yhkeb(v=vs.80).aspx
For "safe" code, you can do something like store your value in an array of length 1, and then only store references to the array and always access the value by array[0], but this is a bit of a hack and there is probably a better way to do what you want to accomplish.

Direct array initialization with a constant value

Whenever you allocate a new array in C# with
new T[length]
the array entries are set to the default of T. That is null for the case that T is a reference type or the result of the default constructor of T, if T is a value type.
In my case i want to initialize an Int32 array with the value -1:
var myArray = new int[100];
for (int i=0; i<myArray.Length; i++) { myArray[i] = -1; }
So after the memory is reserved for the array, the CLR loops over the newly allocated memory and sets all entries to default(int) = 0. After that, my code sets all entries to -1.
That makes the initialization redundant. Does the JIT detect this and neglects the initialization to 0 and if not, is there a way to directly initialize a portion of memory with a custom value?
Referring to C# Array initialization - with non-default value , using Enumerable.Repeat(value, length).ToArray() is no option, because Enumerable.ToArray allocates a new array and copies the values to it afterwards.
Similar to Dan's answer but without the need of using collections:
int[] myArray = Enumerable.Repeat(-1, 100).ToArray();
It's not redundant.
Suppose an exception is thrown during your initialization loop. If the CLR hasn't cleared the memory first, you might be able to "see" the original uninitialized memory, which is a very bad idea, particularly from a security standpoint. That's why the CLR guarantees that any newly allocated memory is wiped to a 0 bit pattern.
The same argument holds for fields in an object, by the way.
I suppose in both cases the CLR could check that you're not going to make the array visible elsewhere before finishing initialization, but it's a complicated check to avoid a pretty simple "wipe this area of memory".
If you buy into Arrays considered somewhat harmful, then your question would be moot as you would write:
var myArray = new List<int>(Enumerable.Repeat(-1, 100));
I highly doubt that the JIT will optimize away the default set for this scenario. The reason being is that this would be an observable difference. Consider the following slightly altered scenario.
obj.myArray = new int[100];
for (int i=0; i<myArray.Length; i++) { obj.myArray[i] = -1; }
It's entirely possible for the loop to throw. At least, it's probably not possible for the JIT to prove it doesn't. If it did throw and the CLR did not default initialize the memory, the result would be observable if you still had a reference to obj.
I suggest using Array.Fill as a very succint way to fill an array with an initial value:
bool[] isPrime = new bool[MaxNum];
Array.Fill(isPrime, true);
This initializes all values in the isPrime array to true.
If you are looking for one liner solution then you could use below:
var myArray = Array.ConvertAll(new int[100], i => -1);

Categories