Gentlefolk,

Using C# in VS 2005.

I have a struct (some components deleted for simplicity) :

public struct CoOrdData
      {
        public int[] coOrdMaxArray;  // = new int[3]; // XYZ co-ord maximum 
		..
		..
      }

This is used in the following objects:

public CoOrdData GraphData  = new CoOrdData();      
    public CoOrdData trackGraph = new CoOrdData();

In the constructor for the surrounding class I have:

// Graph parameters,set the size (3) of the array
       GraphData.coOrdMaxArray  = new int[3];
       trackGraph.coOrdMaxArray = new int[3];

This is done to establish the size of the array as you cant set the size in the struct.

All compiles clean, however during execution of an event on the surrounding class the following code corrupts things,

trackGraph.coOrdMaxArray[0] = GraphData.coOrdMaxArray[0] + (midX - adjX);

trackGraph.coOrdMaxArray[0] AND GraphData.coOrdMaxArray[0] are both set to (midX - adjX)!!!!!!

Extensive reading about value/reference and any example/tutorials on arrays and structures has not helped.

Any soultions/ideas/comments appreciated, Ian

Recommended Answers

All 3 Replies

Do you ever have a statement to the effect of

GraphData = trackGraph;

or vice versa? Because from that point forward, you'll be referencing the same object in memory (or so the program will have you believe).

class Program
    {
        static void Main(string[] args)
        {
            CoOrdData GraphData = new CoOrdData();
            CoOrdData trackGraph = new CoOrdData();

            GraphData.coOrdMaxArray = new int[3];
            trackGraph.coOrdMaxArray = new int[3];

            GraphData = trackGraph;

            int midX = 50;
            int adjX = 10;
            trackGraph.coOrdMaxArray[0] = GraphData.coOrdMaxArray[0] + (midX - adjX);

            Console.WriteLine(trackGraph.coOrdMaxArray[0]);
            Console.WriteLine(GraphData.coOrdMaxArray[0]);

            Console.Read();
        }
    }

    public struct CoOrdData
    {
        public int[] coOrdMaxArray;
    }

That sort of goes against what you think of with structs, being value types. You should be able to say GraphData = trackGraph without issue. In fact, if you remove the array and use just an integer, you can do just that. The code below keeps the structs independent of one another:

class Program
    {
        static void Main(string[] args)
        {
            CoOrdData GraphData = new CoOrdData();
            CoOrdData trackGraph = new CoOrdData();

            GraphData = trackGraph;

            int midX = 50;
            int adjX = 10;
            trackGraph.Storage = GraphData.Storage + (midX - adjX);

            Console.WriteLine(trackGraph.Storage);
            Console.WriteLine(GraphData.Storage);

            Console.Read();
        }
    }

    public struct CoOrdData
    {
        public int Storage;
    }

So what's the deal? Well, as it turns out, your structs in either case are still unique. However, it is the reference to the array that is getting hosed. You set the one struct equal to the other, the fields and references copy over. Your value-type fields are still independent, but now your array references are pointing to the same objects in memory.

class Program
    {
        static void Main(string[] args)
        {
            CoOrdData GraphData = new CoOrdData();
            CoOrdData trackGraph = new CoOrdData();

            GraphData.ArrayStorage = new int[3];
            trackGraph.ArrayStorage = new int[3];

            GraphData = trackGraph;

            int midX = 50;
            int adjX = 10;
            trackGraph.Storage = GraphData.Storage + (midX - adjX);
            trackGraph.ArrayStorage[0] = 15;

            Console.WriteLine(trackGraph.Storage); // writes 40
            Console.WriteLine(GraphData.Storage); // writes 0, still unique
            Console.WriteLine(trackGraph.ArrayStorage[0]); // writes 15
            Console.WriteLine(GraphData.ArrayStorage[0]); // writes 15 again

            Console.Read();
        }
    }

    public struct CoOrdData
    {
        public int Storage;
        public int[] ArrayStorage;
    }
commented: Shows great knowledge. +6

Thank you for your rapid and detailed response. Yes I did have a statement "trackGraph = GraphData", it was executed back in some initialisation code.

How to fix/get-around the problem?

It looks Ok if rather than move the entire object with "trackGraph = GraphData" I move the array components of the struct individually as for example:

trackGraph.coOrdMaxArray[0] = GraphData.coOrdMaxArray[0]

Ugly, but as it is only done once it is managable.

Once again thanks, Ian

To simplify your life a bit, you can use Array.CopyTo() to expedite matters.

int[] array1 = new int[3] {1,2,3};
    int[] array2 = new int[3] {0,0,0};
    array1.CopyTo(array2, 0);

One line to copy it, but the arrays are still independent of one another.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.