linux 查找和防止StackOverflow

f0ofjuux  于 2023-04-20  发布在  Linux
关注(0)|答案(1)|浏览(197)

我有一个代码,似乎在我的计算机上的Visual Studio代码(Windows 11,C#,最新更新和最新的一切),但不是在测试的一个,它使用的是Mono编译器(Linux,C# 7兼容)。唯一不同的是,有 * 是空 *,我把它改为 *==空 *,因为它不会运行,否则。

// BitMatrix.cs
using System;
using System.Collections;
using System.Collections.Generic;

public class BitMatrix : IEquatable<BitMatrix>
{
    private BitArray data;
    public int NumberOfRows { get; }
    public int NumberOfColumns { get; }
    public bool IsReadOnly => false;
    public BitMatrix(int numberOfRows, int numberOfColumns, params int[] bits)
    {
        if (numberOfRows < 1 || numberOfColumns < 1)
            throw new ArgumentOutOfRangeException("Incorrect size of matrix");
        data = new BitArray(numberOfRows * numberOfColumns, false);

        if (bits != null)
        {
            for (int i = 0; i < bits.Length && i < data.Length; i++)
            {
                if (bits[i] != 0)
                    data[i] = true;
            }
        }

        NumberOfRows = numberOfRows;
        NumberOfColumns = numberOfColumns;
    }

    public BitMatrix(int[,] bits)
    {
        if (bits == null)
            throw new NullReferenceException("bits cannot be null");

        int numberOfRows = bits.GetLength(0);
        int numberOfColumns = bits.GetLength(1);

        if (numberOfRows < 1 || numberOfColumns < 1)
            throw new ArgumentOutOfRangeException("Incorrect size of matrix");

        data = new BitArray(numberOfRows * numberOfColumns, false);

        for (int row = 0; row < numberOfRows; row++)
        {
            for (int col = 0; col < numberOfColumns; col++)
            {
                if (bits[row, col] != 0)
                    data[row * numberOfColumns + col] = true;
            }
        }

        NumberOfRows = numberOfRows;
        NumberOfColumns = numberOfColumns;
    }

    public BitMatrix(bool[,] bits)
    {
        if (bits == null)
            throw new NullReferenceException("bits cannot be null");

        int numberOfRows = bits.GetLength(0);
        int numberOfColumns = bits.GetLength(1);

        if (numberOfRows < 1 || numberOfColumns < 1)
            throw new ArgumentOutOfRangeException("Incorrect size of matrix");

        data = new BitArray(numberOfRows * numberOfColumns, false);

        for (int row = 0; row < numberOfRows; row++)
        {
            for (int col = 0; col < numberOfColumns; col++)
            {
                if (bits[row, col])
                    data[row * numberOfColumns + col] = true;
            }
        }

        NumberOfRows = numberOfRows;
        NumberOfColumns = numberOfColumns;
    }

    public static int BoolToBit(bool boolValue) => boolValue ? 1 : 0;
    public static bool BitToBool(int bit) => bit != 0;

    public override string ToString()
    {
        var result = "";
        for (int row = 0; row < NumberOfRows; row++)
        {
            for (int col = 0; col < NumberOfColumns; col++)
            {
                int index = row * NumberOfColumns + col;
                result += BoolToBit(data[index]);
            }
            result += Environment.NewLine; // dodanie znaku końca linii
        }
        return result;
    }

    public bool Equals(BitMatrix? matrix)
    {
        if (matrix is null || NumberOfRows != matrix.NumberOfRows || NumberOfColumns != matrix.NumberOfColumns) return false;

        for (int i = 0; i < data.Length; i++)
        {
            if (data[i] != matrix.data[i]) return false;
        } 

        return true;
    }

    public override bool Equals(object? obj)
    {
        if (obj == null || GetType() != obj.GetType()) return false;
        else return Equals((BitMatrix)obj);
    }

    public override int GetHashCode()
    {
        int hash = 17;
        hash = hash * 23 + NumberOfRows.GetHashCode();
        hash = hash * 23 + NumberOfColumns.GetHashCode();
        
        for (int i = 0; i < data.Length; i++)
        {
            hash = hash * 23 + data[i].GetHashCode();
        }
        return hash;
    }

    public static bool operator ==(BitMatrix matrix1, BitMatrix matrix2)
    {
        if (ReferenceEquals(matrix1, matrix2)) return true;

        if (matrix1 is null || matrix2 is null) return false;

        return matrix1.Equals(matrix2);
    }

    public static bool operator !=(BitMatrix matrix1, BitMatrix matrix2)
    {
        return !(matrix1 == matrix2);
    }
}

在主文件(Program.cs)上,当使用以下命令时,它应该返回True(在我的comp上它确实如此!),

// `Equals` for the same object
var m1 = new BitMatrix(5, 6);
var m2 = m1;
Console.WriteLine(m1.Equals(m2));

但它却返回

Unhandled Exception:
StackOverflowException
[ERROR] FATAL UNHANDLED EXCEPTION: System.StackOverflowException: The requested operation caused a stack overflow.
  at BitMatrix.op_Equality (BitMatrix matrix1, BitMatrix matrix2) <0x40c71820 + 0x00004> in <ee17de3584e0451aa17782759cde6afe>:0
fhity93d

fhity93d1#

好的,我通过在public bool Equals(BitMatrix matrix)中添加if (object.ReferenceEquals(this, matrix)) return true;来手动检查对象是否是相同的示例来修复它。我想Mono编译器本身不会这样做。

相关问题