Строки в Java неизменяемы. Это означает, что всякий раз, когда вы пытаетесь изменить / изменить строку, вы получаете новый экземпляр. Вы не можете изменить исходную строку. Это сделано для того, чтобы эти экземпляры строк могли кэшироваться. Типичная программа содержит множество ссылок на строки и кеширование этих экземпляров, что может уменьшить объем памяти и увеличить производительность программы.
При использовании оператора == для сравнения строк вы не сравниваете содержимое строки , но фактически сравнивают адрес памяти. Если они равны, в противном случае они вернут true и false. Если значение равно в строке, сравнивает содержимое строки.
Итак, вопрос в том, что все строки кэшируются в системе, как получается ==
возвращает false, тогда как equals возвращает true? Ну, это возможно. Если вы создадите новую строку, например String str = new String("Testing")
, вы создадите новую строку в кеше, даже если в кеше уже содержится строка с тем же содержимым. Короче говоря, "MyString" == new String("MyString")
всегда будет возвращать false.
Java также говорит о функции intern (), которая может использоваться в строке, чтобы сделать ее частью кеша, поэтому "MyString" == new String("MyString").intern()
вернет true.
Примечание: == оператор намного быстрее, чем равен только потому, что вы сравниваете два адреса памяти, но вы должны быть уверены, что код не создает новые экземпляры String в коде. В противном случае вы столкнетесь с ошибками.
Это не имеет никакого отношения к выделению памяти как таковой.
Проблема в этих строках
int zerosneeded = length - tmp.size();
while (zerosneeded != 0) {
tmp.push_back(0);
zerosneeded--;
}
, не зная, почему он делает то, что делает, у меня возникает вопрос, глядя на код: «Может ли zerosneeded
быть меньше нуля?». Тем более что zerosneeded
определяется как int
вместо unsigned int
(применимо к остальной части кода).
Если значение нуля меньше нуля, будет бесконечный цикл распределения до исчерпания. Быстрая проверка подтверждает это:
int zerosneeded = length - tmp.size();
if(zerosneeded < 0)
{
std::cout << "fatal, zerosneeded < 0 \n";
throw std::runtime_exception("fatal, zerosneeded < 0");
}
Надеюсь, это поможет в вашей отладке.
Редактировать
Относительно того, почему нули нужны, является отрицательным:
, во-первых, вычисляется количество возможностей, которое является длиной символов.
int possibilities = std::pow(symbols, length);
при отправке значений в tmp мы в основном находим первый x такой, что длина ^ x> частное. Частное находится в диапазоне [0, символы ^ длина] и используется push-значениями в tmp.
int quotient = i;
while (quotient!=0) {
tmp.push_back(quotient % length);
quotient = quotient / length;
}
Если символы ^ длина> длина ^ длина, первый x такой, что длина ^ x> частное, дает x> длину, в результате чего int zerosneeded = length - tmp.size();
становится отрицательным.
Для примера мы имеем длину = 4, символы = 6, поэтому коэффициенты имеют диапазон [0,6 ^ 4] = [0, 1296]. Но уже для 256 мы имеем 4 ^ 4 = 256 => 4 ^ 5> 256, поэтому наш x = 5 => zerosneeded = 4 - 5 = -1.
Это ничего особенного для длины = 4 и символов = 6, и на самом деле должно происходить до тех пор, пока длина < символов.