Что такое переполнение стека?

Рассмотрим свойство order схем flex и grid.

В приведенных ниже примерах я сосредоточусь на flexbox, но те же понятия применимы к Grid.


С помощью flexbox можно смоделировать предыдущий селектор сиблинга.

В частности, свойство flex order может перемещать элементы вокруг экрана.

Пример:

Вы хотите, чтобы элемент A загорелся, когда элемент B зависает.

  • A
  • B
blockquote>

ШАГИ

  1. Сделайте контейнер ul гибким.
    ul { display: flex; }
    

  1. Отменить порядок братьев и сестер в надписи.
    • B
    • A

  1. Используйте селектор для подключения к элементу A (~ или +).
    li:hover + li { background-color: red; }
    

  1. Используйте свойство flex order, чтобы восстановить порядок братьев и сестер на визуальном дисплее.
    li:last-child { order: -1; }
    

... и voilà! Предыдущий родитель (или, по крайней мере, имитируемый) родился [или g28]

Вот полный код:

ul {
    display: flex;
}

li:hover + li {
    background-color: red;
}

li:last-child {
    order: -1;
}

/* non-essential decorative styles */
li {
    height: 200px;
    width: 200px;
    background-color: aqua;
    margin: 5px;
    list-style-type: none;
    cursor: pointer;
}
  • B
  • A

Из спецификации flexbox:

5.4. Порядок отображения: свойство order

Элементы Flex по умолчанию отображаются и выкладываются в том же порядке, что и в исходном документе. Свойство order можно использовать для изменения этого заказа.

Свойство order управляет порядком, в котором элементы гибкости появляются в контейнере flex, назначая их порядковым группам. Он принимает одно значение , которое указывает, к какой порядковой группе принадлежит элемент flex.

blockquote>

Начальное значение order для всех элементов flex равно 0.

Также см. order в спецификации CSS Grid Layout spec .


Примеры «предыдущих селекторов севера», созданных с использованием свойства flex order.

.container { display: flex; }

.box5 { order: 1; }    
.box5:hover + .box4 { background-color: orangered; font-size: 1.5em; }

.box6 { order: -4; }
.box7 { order: -3; }
.box8 { order: -2; }
.box9 { order: -1; }
.box9:hover ~ :not(.box12):nth-child(-1n+5) { background-color: orangered;
                                              font-size: 1.5em; }
.box12 { order: 2; }
.box12:hover ~ :nth-last-child(-1n+2) { background-color: orangered;
                                        font-size: 1.5em; }
.box21 { order: 1; }
.box21:hover ~ .box { background-color: orangered; font-size: 1.5em; }

/* non-essential decorative styles */
.container {
    padding: 5px;
    background-color: #888;
}
.box {
    height: 50px;
    width: 75px;
    margin: 5px;
    background-color: lightgreen;
    display: flex;
    justify-content: center;
    align-items: center;
    text-align: center;
    cursor: pointer;
}

Using the flex order property to construct a previous sibling selector

1
2
3
HOVER ME
4

HOVER ME
HOVER ME
6
7
8
10
11

HOVER ME
13
14
15
16
17
18
19
20

jsFiddle


A Side Note & ndash; Две устаревшие убеждения о CSS

Flexbox разрушает давние убеждения в отношении CSS.

Одно из таких убеждений заключается в том, что предыдущий селектор сиблинга невозможен в CSS .

Сказать, что это убеждение широко распространено, было бы преуменьшением. Ниже приведена выборка связанных вопросов только для переполнения стека:

Как описано выше, это убеждение не совсем верно. Предыдущий сингл-селектор может быть смоделирован в CSS с использованием свойства flex order.

Миф z-index

Еще одно давнее убеждение что z-index работает только с расположенными элементами.

Фактически, самая последняя версия spec & ndash; Проект редактора W3C & ndash; все еще утверждает, что это правда:

9.9.1 Определение уровня стека: свойство z-index

z-index

  • Значение: auto | | inherit
  • Начальное: auto
  • Применяется к: позиционированным элементам
  • Inherited: no
  • Процент: N / A
  • Медиа: визуальный
  • Вычисленное значение: как указано

(выделено курсивом)

blockquote>

В действительности, однако, эта информация устарела и неточна.

Элементы, которые являются элементами гибких элементов или , могут создавать (f28) static.

4.3. Элемент Flex Item Z-Ordering

Элементы Flex представляют собой то же самое, что и встроенные блоки, за исключением того, что порядок ортогонального заказа используется вместо необработанного порядка документа и значения z-index, отличные от auto создать контекст стекирования, даже если position - static.

5.4. Z-axis Ordering: свойство z-index

Порядок рисования элементов сетки точно такой же, как и встроенные блоки, за исключением того, что порядок ортогонального заказа используется вместо необработанного порядка документа и z-index, отличные от auto, создают контекст стекирования, даже если position - static.

blockquote>

Ниже приведена демонстрация работы z-index над непозиционированными элементами гибкости: https://jsfiddle.net/m0wddwxs/

35
задан joe 21 July 2009 в 15:55
поделиться

6 ответов

Из Википедия :

В программном обеспечении происходит переполнение стека когда слишком много памяти используется на стек вызовов. Во многих программах языков стек вызовов содержит ограниченный объем памяти, обычно определено в начале program.

Стек - это структура данных, в которой хранится запись о том, в какой момент подпрограммы программы должны вернуть управление после завершения выполнения. Адреса возврата помещаются в стек, когда подпрограммы вызываются, когда подпрограмма завершает свое выполнение, адрес возврата извлекается из стека. Если существует много подпрограмм и нет места в стеке, происходит переполнение стека.

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

Википедия включает красивую диаграмму, изображающую стек, когда подпрограмма DrawLine вызывается из другой подпрограммы, называемой DrawSquare , Я надеюсь, что это изображение поможет лучше понять структуру стека.

stack diagram

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

Guffa вклад: Стек не имеет ничего общего со сборкой мусора. Современные приложения имеют больший стек, что немного снижает вероятность переполнения стека, но в остальном разницы нет.

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

Guffa вклад: Стек не имеет ничего общего со сборкой мусора. Современные приложения имеют больший стек, что немного снижает вероятность переполнения стека, но в остальном разницы нет.

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

Guffa вклад: Стек не имеет ничего общего со сборкой мусора. Современные приложения имеют больший стек, что немного снижает вероятность переполнения стека, но в остальном разницы нет.

26
ответ дан 27 November 2019 в 07:10
поделиться

Переполнение стека происходит, когда логическая структура стека становится слишком полной рекурсивных вызовов метода без условия основы/завершения. В типичной программе, Ваших примитивных переменных, например, целое число, плавание, и т.д. хранится в хитрости физической памяти Ваши вызовы метода, сохраненные в логической структуре данных, такие как стек. Стек хранит данные с последовательностью метода "последним пришел - первым вышел" (LIFO).

Main(){ 
 foo(3); 
 } 

 foo(n){
  if(n<1) // recursion with base condition that terminates when n<1
   return;
  else foo(n-1); 
  print ('Hello' + n);
 }

enter image description here

без основного условия if(n<1) return, метод foo(n) рекурсивно назовет себя, пока больше не будет комнаты в стеке, следовательно переполнение стека.

0
ответ дан 27 November 2019 в 07:10
поделиться

Стек содержит несколько кадров стека и хранится в памяти. Каждый раз, когда вызывается функция, в стек добавляется новый кадр стека. Кадр стека содержит аргументы, которые должны быть переданы вызываемой функции, и адрес возврата, так что, когда вызываемая функция завершит работу, ЦП знает, куда вернуться, чтобы он мог продолжить выполнение вызывающей функции. Фрейм стека также может содержать память, которая будет использоваться локальными переменными вызываемой функции.

В этом примере функция Main называется WriteCustomerDetails, а функция PrintToConsole - для записи отдельных битов данных, которые функция WriteCustomerDetails искала:

'======= верх стека ====================='
Функция: PrintToConsole
Арг: Джон Смит, 34 Акация-авеню, 23 года
'------------------------------------------------- ---------- '
Функция: WriteCustomerDetails
Арг: Джон Смит
'------------------------------------------------- ---------- '
Функция: Main
'====== дно стека ==================='

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

Переполнение стека часто может произойти, когда случайно написана функция, которая вызывает сама себя. Иногда функция может вызывать сама себя, если в функции есть «если» или какое-то условие, которое останавливает вызовы в какой-то момент. Это называется рекурсивной функцией. Но, если остановки нет, и функция продолжает вызывать себя, или, может быть, две или более функций продолжают вызывать друг друга, то очень быстро они съедят всю память стека. Когда ничего не остается, происходит переполнение стека, и программа вылетает.

Это может произойти в любой программе, они не обязательно должны быть сложными, и это может произойти в коде, запускающем веб-сайт. И это также может происходить в языках сценариев.

18
ответ дан 27 November 2019 в 07:10
поделиться

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

Первая - когда в коде есть ошибка, вызывающая рекурсивный цикл без выхода. Например, свойство, считывающее само себя:

public int Length {
   get {
      return Length;
   }
}

Второй - когда у вас слишком глубокий рекурсивный цикл. Поскольку пространство стека ограничено, вы можете вложить алгоритм только определенное количество раз. Если ваш алгоритм слишком глубоко вложен, так что у него заканчивается пространство стека до того, как он существует, вы получаете переполнение стека. Пример:

public bool Odd(int value) {
   if (value == 0) {
      return false;
   } else {
      return !Odd(value - 1);
   }
}

Если вы вызовете этот метод со слишком большим значением, он будет слишком глубоким и вызовет переполнение стека.

7
ответ дан 27 November 2019 в 07:10
поделиться

Из wikipedia , например:

В программном обеспечении переполнение стека происходит, когда в стеке вызовов используется слишком много памяти. Во многих языках программирования стек вызовов содержит ограниченный объем памяти, обычно определяемый в начале программы. Размер стека вызовов зависит от многих факторов, включая язык программирования, архитектуру машины, многопоточность и объем доступной памяти. Когда в стеке вызовов используется слишком много памяти, говорят, что стек переполняется; обычно приводит к сбою программы. 1 Этот класс программных ошибок обычно вызывается одним из двух типов ошибок программирования

6
ответ дан 27 November 2019 в 07:10
поделиться

Переполнение стека происходит, когда вы используя стек (да ...), и возникает проблема с распределением / чтением памяти. в "веб-программах",

1
ответ дан 27 November 2019 в 07:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: