Search code examples
c#s

Getting a stack overflow exception when normalizing a vector


I'm making a Vector class in C#, with a normalized parameter, which is the vector normalized. However, when I'm trying to calculate the normalized Vector, I get a stack overflow exception. Is there a better way to do it? Here is my code (inside the constructor):

namespace Vector3
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Vector3 vector = new(3, 4, 0);
            Console.WriteLine(vector.magnitude);
            Console.WriteLine(vector.normalized);
        }
    }



    class Vector3
    {
    
        public float x, y, z;
        public readonly float magnitude;
        public readonly Vector3 normalized;

        public Vector3(float x, float y, float z)
        {
            this.x = x;
            this.y = y;
            this.z = z;

            this.magnitude = Convert.ToSingle(Math.Sqrt(Math.Pow(this.x, 2) + Math.Pow(this.y, 2) + Math.Pow(this.z, 2)));
            this.normalized = new Vector3(this.x/this.magnitude, this.y/this.magnitude, this.z/this.magnitude);
            
        }
    }
}

Solution

  • You have infinite recursion in the constructor. While you creating Vector3, you create another Vector3 inside the constructor for normalized value. And this cycle never ends and finally gives you StackOverflowException

    You can use lazy creation of normalized value as shown below.

    using System;
    
    namespace Vector3
    {
        internal class Program
        {
            static void Main(string[] args)
            {
                Vector3 vector = new(3, 4, 0);
                Console.WriteLine(vector.magnitude);
                Console.WriteLine(vector.normalized);
            }
        }
    
        class Vector3
        {
            public readonly float x, y, z;
            public readonly float magnitude;
            
            private Vector3 _normalized = null;
            public Vector3 normalized => _normalized ??= new(this.x/this.magnitude,
                                                   this.y/this.magnitude, this.z/this.magnitude);
    
            public Vector3(float x, float y, float z)
            {
                this.x = x;
                this.y = y;
                this.z = z;
    
                this.magnitude = Convert.ToSingle(Math.Sqrt(Math.Pow(this.x, 2) + Math.Pow(this.y, 2) + Math.Pow(this.z, 2)));
            }
        }
    }