none
Переход от class к struct Ошибка: StackOverFlow RRS feed

  • Вопрос

  • Почему возникает эта ошибка. Как от нее избавится? В классе у меня членов более 20, класс(структура) используется для построения коллекций ObservableCollection.


    Eugene


    19 августа 2013 г. 9:57

Ответы

  • Я начал переход по одному классу, после каждой замены проверяю работоспособность и сохраняю копию. Все идет без ошибок. Любопытно конечно понять  куда именно ходила программа при обращении к функции.

    Eugene

    • Помечено в качестве ответа Евгений771 20 августа 2013 г. 17:01
    20 августа 2013 г. 17:01

Все ответы

  • Добрый день.

    Если вы приведете код, в котором происходит ошибка, расскажите на каком количестве элементов это воспроизводится и/или выложите демо проект с воспроизводящейся ошибкой, то шансы что вам помогут значительно увеличатся. Ну а так, разная память используется для хранения структур и объектов... Может быть с этим как то связано. Кстати, а зачем вы от класса переходите к структурам?

    19 августа 2013 г. 10:02
    Отвечающий
  • Перехожу там, где данные пишутся только один раз и потом идет только чтение и постоянно приходится добавлять нулевой элемент и последний удалять. Благодаря структуре я смогу член класса передавать по значению(а не по ссылке) и пользоваться циклическим буффером.

     Я понять не могу, почему class работал, а структура работать не хочет. В чем у них разница возникает.

    У меня показывает на функцию, я ставлю брейкпойнт на вход, а до него даже не доходит.

    Данную функцию предоставить не могу, к сожалению.

     void Instrument_EventTickData(IInstrument Instrument, ITick newTick)
            {
    
    
                if (Instrument.Symbol != this.cmbTicker.Text)
                    return;
    
                if (Model != null)
                {
    
                    Model.TickChanges(Instrument, newTick);// ОСТАНОВКА ПРОГРАММЫ
    
    
                }
                //  System.Windows.Forms.Application.DoEvents();
            }
     

    В Model.TickChanges ни разу не заходит.

    В Model  не объявляются ни одна переменная или коллекция класса, который я меняю на структуру.Стоит вернуть обратно и все работает, остановка всегда в одной точке.

    Захожу в Model и там десятки переменных которые не может вычислить т к текущий поток находится в состоянии переполнения стэка.

    C этой структурой только в MainWindow работа была до текущей точки.

     public static ObservableCollection<BarType> MassivBar20tick;
    
    //конструктор
     MassivBar20tick = new ObservableCollection<BarType>();
    // примерный вид структуры там же в MainWindow
    
     public struct BarType
        {
            public DateTime DateTimeOB { get; set; }
            public decimal OpenPrice { get; set; }
            public decimal MaxPrice { get; set; }
            public decimal MinPrice { get; set; }
            public decimal ClosePrice { get; set; }
    ...
    
    ...
    
    ..
    }


    Eugene




    19 августа 2013 г. 10:25
  • Кстати, что то я туплю. У вас же ошибка не OutOfMemory, а StackOverFlow. Может у вас там рекурсия где есть? Такое ощущение, что вызовом методов очень много.

    Вот такой код, в котором создаются 8 с лишним миллионов объектов, падает именно на OutOfMemory:

    struct Test
    {
        public string a;
    
        public string c;
    
        public int b;
    }
    
    static void Main(string[] args)
    {
        List<Test> a = new List<Test>();
        Random rnd = new Random();
        while (true)
        {
            Test t;
            t.a = "dsfghjkhgfdsa" + rnd.Next(1000000000);
            t.c = "liokujhgfqgrswadfgsdfbsdf" + rnd.Next(1000000000);
            t.b = 10;
            a.Add(t);
        }
    }

    19 августа 2013 г. 10:39
    Отвечающий
  • А как может быть рекурсия при без входа в функцию? и почему замена на class сразу возвращает программу в рабочее состояниие? У меня программа работает с on line данными и работает сутками, была бы где рекурсия, то такого бы не было.

    Вообще тип BarType у меня локально используется и вход в зону работы с ним я могу отследить, но не доходит.

    Хотя память росла с 120 Мб до 1 Гб и так и не нашел причину, 4 профилировщиками гонял. Это так, в сторону от вопроса ушел.


    Eugene



    19 августа 2013 г. 10:50
  • StackOverflowException - "Исключение, которое выбрасывается при переполнении стека выполнения из-за чрезмерного количества вложенных вызовов метода."

    Ищите в своем коде вложенные вызовы. А чтобы разобраться со структурами и классами - читайте про ссылочные и значимые типы, это будет полезно!

    19 августа 2013 г. 11:01
  • Вот какие вложенные? Перед вызовом функции Model.TickChanges в первый раз с Model  все нормально и без ошибок. Затем программа уходит в Model.TickChanges, но брейкпойнты на входе не ловят, секунд 5-10 там находится и на выходе уже с Model много ошибок. Это на первом же тике(это обработчик тиков). Вот что там программа делала и где?

    Функция эта вызывается только в одном месте.

    И как смена второстипенного класса на структуру повлияла на это?


    Eugene



    19 августа 2013 г. 11:32
  • Вот какие вложенные? Вот что там прогамма делала и где?

    Если бы у меня был полный код, тогда бы я вам сказал. А так только могу посоветовать все внимательно просмотреть. Попробуйте вход в функцию выполнить в отладке через F11, может обнаружите что.

    И как смена второстипенного класса на структуру повлмяла на это?

    О-о-о... Может и не такое быть!

    19 августа 2013 г. 11:39
  • Я хочу понять почему я на входе в функцию не могу остановить программу, значит входа-то и нет фактически?

    После F11 пишет он по многим переменным, что их невозможно вычислить т е текущий потк в состоянии переполнения стэка, это никакой информации не дает о том где именно это переполнение произошло.

    Я вот такой схемой пользовался при переходе к структурам:

    OpenBook temp=OpenBookAsk[i];
    temp.DateTimeOB=newTick.DateTime;
    OpenBookAsk[i]=temp;
    Понимать бы еще как первый раз вход в функцию происходит и как инициализируются они.

    ErrorOverFlowStack1


    Eugene




    19 августа 2013 г. 12:14
  • Когда произойдет exception посмотрите в окошко Стек вызова

    Вот тут я смоделировал ситуацию когда у меня возникает такая же ошибка. То есть функция вызывает сама себя бесконечно, в итоге и происходит переполнение стека. Если вы посмотрите на стрелку то вот это "Стек вызвов", так вот, видите там описана вся последовательность вызовов методов. то есть в моем случае это метод f().

    Так же и у себя при возникновении исключения, посмотрите это окно и определите какая функция вызывает сама себя


    • Изменено Higgs.Boson 20 августа 2013 г. 11:31 Корректировка
    20 августа 2013 г. 11:30
  • Я начал переход по одному классу, после каждой замены проверяю работоспособность и сохраняю копию. Все идет без ошибок. Любопытно конечно понять  куда именно ходила программа при обращении к функции.

    Eugene

    • Помечено в качестве ответа Евгений771 20 августа 2013 г. 17:01
    20 августа 2013 г. 17:01
  • Ошибка связана с операцией:

    public T ElementAt(int index)
           {
               if ((index >= plainBuffer.Length) || (index < 0))
                   throw new IndexOutOfRangeException();
    
               index += _startIndex;
    
               if (index >= plainBuffer.Length)
                   index -= plainBuffer.Length;
    
               return plainBuffer[index];
           }

    По возможности стал создавать:


    TypeStruct Temp= NameStruct.ElementAt(0);

    Я слишком много обращений делал вида:

     X=NameStruct.ElementAt(0).Price;

    т е к элементам обращался сразу много раз.

    С классами таких проблем нет, с чем это связано?И какой самый быстрый способ доступа к даннным моего циклического массива к отдельным свойствам элемента массива?И чтобы переполнения стэка не было при большом количестве операций. Каждый раз загружать целый элемент массива наверное плохо сказывается на производительности.


    Eugene


    21 августа 2013 г. 20:43