From what I understand, when assigning a struct variable to another one, the first one is usually copied instead of creating a reference:
public struct MYSTRUCT1
{
public byte val1;
}
// (...)
public DoSomething() {
MYSTRUCT1 test1;
test1.val1 = 1;
MYSTRUCT1 test2 = test1;
test2.val1 = 2;
Console.WriteLine(test1.val1);
Console.WriteLine(test2.val1);
}
This works just fine, the output is:
1
2
However, if I have a byte[] inside my struct, this behaviour changes:
public struct MYSTRUCT1
{
public byte[] val1;
}
// (...)
public DoSomething() {
MYSTRUCT1 test1;
test1.val1 = new byte[0x100];
test1.val1[0] = 1;
MYSTRUCT1 test2 = test1;
test2.val1[0] = 2;
Console.WriteLine(test1.val1[0]);
Console.WriteLine(test2.val1[0]);
}
This is the output:
2
2
How can I avoid this? I really need to work with a copy of the complete struct including any byte arrays.
Thank you! ♪
Edit: Thanks for all your help! In order to deep copy my struct, I’m now using this code:
public static object deepCopyStruct(object anything, Type anyType)
{
return RawDeserialize(RawSerialize(anything), 0, anyType);
}
/* Source: http://bytes.com/topic/c-sharp/answers/249770-byte-structure */
public static object RawDeserialize(byte[] rawData, int position, Type anyType)
{
int rawsize = Marshal.SizeOf(anyType);
if (rawsize > rawData.Length)
return null;
IntPtr buffer = Marshal.AllocHGlobal(rawsize);
Marshal.Copy(rawData, position, buffer, rawsize);
object retobj = Marshal.PtrToStructure(buffer, anyType);
Marshal.FreeHGlobal(buffer);
return retobj;
}
/* Source: http://bytes.com/topic/c-sharp/answers/249770-byte-structure */
public static byte[] RawSerialize(object anything)
{
int rawSize = Marshal.SizeOf(anything);
IntPtr buffer = Marshal.AllocHGlobal(rawSize);
Marshal.StructureToPtr(anything, buffer, false);
byte[] rawDatas = new byte[rawSize];
Marshal.Copy(buffer, rawDatas, 0, rawSize);
Marshal.FreeHGlobal(buffer);
return rawDatas;
}
It must be called like this:
MYSTRUCT1 test2 = (MYSTRUCT1)deepCopyStruct(test1, typeof(MYSTRUCT1));
This seems to work fine, though I’m aware that this is dirty code.
However, since the structs I’m working with have over 50 byte[]
several other structs in them, it’s just too much work to write Copy()
/Clone()
methods for each of them.
Suggestions for better code are of course very welcome.
C strcpy() The strcpy() function copies the string pointed by source (including the null character) to the destination. The strcpy() function also returns the copied string.
The strcpy() function copies string2, including the ending null character, to the location that is specified by string1. The strcpy() function operates on null-ended strings. The string arguments to the function should contain a null character (\0) that marks the end of the string. No length checking is performed.
You could use strdup() to return a copy of a C-string, as in: #include <string. h> const char *stringA = "foo"; char *stringB = NULL; stringB = strdup(stringA); /* ... */ free(stringB);
The strcpy() function does not stop until it sees a zero (a number zero, '<0') in the source string. Since the source string is longer than 12 bytes, strcpy() will overwrite some portion of the stack above the buffer.
You will have to create a Clone
method to do a deep copy of the struct's members:
public struct MyStruct
{
public byte[] data;
public MyStruct Clone()
{
byte[] clonedData = new byte[this.data.Length];
data.CopyTo(clonedData, 0);
return new MyStruct { data = clonedData };
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With