Куда уходит память, используемая для строки, когда строковой переменной присваивается новое значение?

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

$(document).ready(function(){
  //Particular Parent chield click
  $(".buttons").on("click","button",function(){
    alert("Clicked");
  });  
  
  //Dynamic event bind on button class  
  $(document).on("click",".button",function(){
    alert("Dymamic Clicked");
  });
  $("input").addClass("button");  
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="buttons">
  <input type="button" value="1">
  <button>2</button>
  <input type="text">
  <button>3</button>  
  <input type="button" value="5">  
  </div>
<button>6</button>

3
задан Curious Learner 28 March 2019 в 02:46
поделиться

5 ответов

Из того, что я знаю, строка просто копируется в память, выделенную для a_string, поскольку она более эффективна, чем освобождение памяти и выделение новой. Если память, выделенная для (a + a), меньше, чем размер, выделенный для a_string, она изменяется.

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

std :: string и автоматическое изменение размера памяти

0
ответ дан Suven Pandey 28 March 2019 в 02:46
поделиться

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

Тогда a+a, что вы не можете избежать.

затем интересная часть:

(b + b) + b, которые создают 2 распределения для 2 временных.

затем вы используете назначение перемещения, которое заменяет a_string на временное: нет выделения.

0
ответ дан Jarod42 28 March 2019 в 02:46
поделиться

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

0
ответ дан EnigmaticBacon 28 March 2019 в 02:46
поделиться

std::string - это класс менеджера ресурсов. Он владеет базовым char*. Выделенная память получает delete d, как только вызывается деструктор объекта std::string, т.е. когда сам объект выходит из области видимости.

То же самое происходит, когда std::string переназначается. Старая память будет освобождена, если она будет маленькой для новой строки и потенциально будет заменена новой памятью кучи. Классы Ressource Management, такие как std::string, имеют сильную гарантию никогда не пропускать память (при условии реализации в соответствии со стандартами).

Поскольку вы назначаете временную копию, копирование (и, следовательно, перераспределение) не требуется. Вместо этого содержимое временного b + b + b будет перемещено в строку. Это означает копирование основного указателя временного объекта в существующий строковый объект и удаление временного владельца этого указателя. Это означает, что временное устройство больше не владеет памятью и, следовательно, не будет delete ее, когда ее деструктор вызывается непосредственно после назначения. Это имеет огромное преимущество: необходимо скопировать только указатель вместо memcpy полной строки.

Другие классы управления ресурсами с такой гарантией включают умные указатели (std::unique_pointer, std::shared_pointer) и коллекции (например, std::vector, std::list, std::map ...).

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

0
ответ дан LukeG 28 March 2019 в 02:46
поделиться

Это зависит от того, является ли это короткой или длинной строкой:

std::string a_string = a + a;
// reassign a new string to a_string
a_string = b + b + b; 

Во-первых, a + a создается непосредственно как a_string благодаря гарантированной копии elison (c ++ 17) , Здесь не происходит освобождения.

Затем, если a_string достаточно короткий, он размещается в стеке без дополнительных распределений кучи. Эта оптимизация коротких строк (SSO) выполняется большинством компиляторов, но не обязана стандартом.

Если SSO имел место, то это не освобождает место в a_string, а просто использует его повторно. Память уходит в никуда:

a_string = b + b + b; 

Однако, если a_string слишком длинный для SSO, то эта строка освобождает пространство кучи, выделенное для строки.

Ясно видеть, куда уходит память, когда проверяется объявление std::string :

template< 
   class CharT,
   class Traits = std::char_traits<CharT>,
   class Allocator = std::allocator<CharT>
> class basic_string;

Память строка без единого входа выделяется и освобождается с помощью std::allocator. Этот распределитель распределяет и освобождает память с помощью операторов new и delete. Обычно они используют malloc / free за кулисами. Так работает malloc и free.

Легко узнать, насколько большой может быть строка SSO, запустив

std::cout << std::string().capacity() << '\n';

Для clang 8.0.0 на 64-битном Intel SSO для строк длиной до 22 символов, а для gcc 8.3 - только 15 символов.

0
ответ дан Michael Veksler 28 March 2019 в 02:46
поделиться
Другие вопросы по тегам:

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